passenger 2.2.15 → 3.0.0.pre1

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 (1338) hide show
  1. data/DEVELOPERS.TXT +21 -12
  2. data/LICENSE +1 -1
  3. data/NEWS +8 -1
  4. data/PACKAGING.TXT +25 -0
  5. data/Rakefile +28 -891
  6. data/bin/passenger +32 -0
  7. data/bin/passenger-config +5 -5
  8. data/bin/passenger-install-apache2-module +37 -24
  9. data/bin/passenger-install-nginx-module +48 -46
  10. data/bin/passenger-make-enterprisey +8 -9
  11. data/bin/passenger-memory-stats +20 -150
  12. data/bin/passenger-status +130 -44
  13. data/bin/passenger-stress-test +5 -4
  14. data/build/agents.rb +73 -0
  15. data/build/apache2.rb +165 -0
  16. data/build/basics.rb +81 -0
  17. data/build/common_library.rb +198 -0
  18. data/build/config.rb +35 -0
  19. data/{misc/rake/cplusplus.rb → build/cplusplus_support.rb} +1 -1
  20. data/build/cxx_tests.rb +205 -0
  21. data/build/documentation.rb +77 -0
  22. data/{misc/rake → build}/gempackagetask.rb +1 -1
  23. data/build/integration_tests.rb +57 -0
  24. data/build/misc.rb +146 -0
  25. data/build/nginx.rb +64 -0
  26. data/build/oxt_tests.rb +52 -0
  27. data/{misc/rake → build}/packagetask.rb +0 -0
  28. data/build/packaging.rb +189 -0
  29. data/{misc/rake/extensions.rb → build/rake_extensions.rb} +1 -1
  30. data/{misc/rake → build}/rdoctask.rb +0 -0
  31. data/build/ruby_extension.rb +46 -0
  32. data/build/ruby_tests.rb +42 -0
  33. data/build/test_basics.rb +31 -0
  34. data/doc/ApplicationPool algorithm.txt +447 -234
  35. data/doc/Architectural overview.html +47 -56
  36. data/doc/Doxyfile +1 -1
  37. data/doc/Security of user switching support.html +46 -57
  38. data/doc/Users guide Apache.html +1033 -306
  39. data/doc/Users guide Apache.txt +419 -99
  40. data/doc/Users guide Nginx.html +1252 -253
  41. data/doc/Users guide Nginx.txt +711 -87
  42. data/doc/Users guide Standalone.html +603 -0
  43. data/doc/Users guide Standalone.txt +40 -0
  44. data/doc/cxxapi/AbstractSpawnManager_8h_source.html +141 -0
  45. data/doc/cxxapi/Account_8h_source.html +206 -0
  46. data/doc/cxxapi/AccountsDatabase_8h_source.html +161 -0
  47. data/doc/cxxapi/AgentBase_8h_source.html +70 -0
  48. data/doc/cxxapi/AgentsStarter_8h_source.html +112 -0
  49. data/doc/cxxapi/BCrypt_8h_source.html +104 -0
  50. data/doc/cxxapi/Blowfish_8h_source.html +134 -0
  51. data/doc/cxxapi/Bucket_8h_source.html +4 -3
  52. data/doc/cxxapi/Constants_8h_source.html +79 -0
  53. data/doc/cxxapi/ContentHandler_8h_source.html +95 -0
  54. data/doc/cxxapi/DirectoryMapper_8h_source.html +9 -8
  55. data/doc/cxxapi/EventedClient_8h_source.html +629 -0
  56. data/doc/cxxapi/EventedMessageServer_8h_source.html +358 -0
  57. data/doc/cxxapi/EventedServer_8h_source.html +326 -0
  58. data/doc/cxxapi/Exceptions_8h_source.html +366 -0
  59. data/doc/cxxapi/FileDescriptor_8h_source.html +260 -0
  60. data/doc/cxxapi/Hooks_8h_source.html +2 -1
  61. data/doc/cxxapi/HttpStatusExtractor_8h_source.html +382 -0
  62. data/doc/cxxapi/Logging_8h_source.html +726 -0
  63. data/doc/cxxapi/MessageChannel_8h_source.html +852 -0
  64. data/doc/cxxapi/MessageClient_8h_source.html +328 -0
  65. data/doc/cxxapi/MessageReadersWriters_8h_source.html +539 -0
  66. data/doc/cxxapi/MessageServer_8h_source.html +606 -0
  67. data/doc/cxxapi/PoolOptions_8h_source.html +548 -0
  68. data/doc/cxxapi/Process_8h_source.html +286 -0
  69. data/doc/cxxapi/RandomGenerator_8h_source.html +191 -0
  70. data/doc/cxxapi/ResourceLocator_8h_source.html +115 -0
  71. data/doc/cxxapi/ScgiRequestParser_8h_source.html +406 -0
  72. data/doc/cxxapi/ServerInstanceDir_8h_source.html +374 -0
  73. data/doc/cxxapi/Session_8h_source.html +501 -0
  74. data/doc/cxxapi/SpawnManager_8h_source.html +647 -0
  75. data/doc/cxxapi/StaticContentHandler_8h_source.html +68 -0
  76. data/doc/cxxapi/StaticString_8h_source.html +254 -0
  77. data/doc/cxxapi/StringListCreator_8h_source.html +114 -0
  78. data/doc/cxxapi/Utils_8h_source.html +442 -0
  79. data/doc/cxxapi/annotated.html +46 -0
  80. data/doc/cxxapi/apache2_2Configuration_8h_source.html +82 -0
  81. data/doc/cxxapi/classAgentWatcher-members.html +30 -26
  82. data/doc/cxxapi/classAgentWatcher.html +168 -194
  83. data/doc/cxxapi/classClient-members.html +14 -11
  84. data/doc/cxxapi/classClient.html +35 -35
  85. data/doc/cxxapi/classHooks-members.html +2 -0
  86. data/doc/cxxapi/classHooks.html +2 -0
  87. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager-members.html +16 -13
  88. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager.html +78 -82
  89. data/doc/cxxapi/classPassenger_1_1ArgumentException-members.html +12 -9
  90. data/doc/cxxapi/classPassenger_1_1ArgumentException.html +26 -22
  91. data/doc/cxxapi/classPassenger_1_1ArrayMessage-members.html +37 -0
  92. data/doc/cxxapi/classPassenger_1_1ArrayMessage.html +113 -0
  93. data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +14 -11
  94. data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +41 -42
  95. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +12 -9
  96. data/doc/cxxapi/classPassenger_1_1BusyException.html +24 -20
  97. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +12 -9
  98. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +23 -19
  99. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -0
  100. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +8 -6
  101. data/doc/cxxapi/classPassenger_1_1EOFException-members.html +12 -9
  102. data/doc/cxxapi/classPassenger_1_1EOFException.html +27 -23
  103. data/doc/cxxapi/classPassenger_1_1EventFd-members.html +12 -9
  104. data/doc/cxxapi/classPassenger_1_1EventFd.html +24 -21
  105. data/doc/cxxapi/classPassenger_1_1EventedClient-members.html +54 -0
  106. data/doc/cxxapi/classPassenger_1_1EventedClient.html +436 -0
  107. data/doc/cxxapi/classPassenger_1_1EventedMessageServer-members.html +37 -0
  108. data/doc/cxxapi/classPassenger_1_1EventedMessageServer.html +59 -0
  109. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.map +3 -0
  110. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.md5 +1 -0
  111. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.png +0 -0
  112. data/doc/cxxapi/classPassenger_1_1EventedServer-members.html +37 -0
  113. data/doc/cxxapi/classPassenger_1_1EventedServer.html +93 -0
  114. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.map +3 -0
  115. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.md5 +1 -0
  116. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.png +0 -0
  117. data/doc/cxxapi/classPassenger_1_1FileDescriptor-members.html +16 -13
  118. data/doc/cxxapi/classPassenger_1_1FileDescriptor.html +63 -70
  119. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +12 -9
  120. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +26 -22
  121. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +17 -14
  122. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +32 -30
  123. data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor-members.html +15 -12
  124. data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor.html +59 -59
  125. data/doc/cxxapi/classPassenger_1_1IOException-members.html +12 -9
  126. data/doc/cxxapi/classPassenger_1_1IOException.html +27 -23
  127. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +36 -33
  128. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +326 -344
  129. data/doc/cxxapi/classPassenger_1_1MessageServer-members.html +25 -22
  130. data/doc/cxxapi/classPassenger_1_1MessageServer.html +160 -191
  131. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext-members.html +12 -9
  132. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext.html +29 -27
  133. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.map +3 -1
  134. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.md5 +1 -1
  135. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.png +0 -0
  136. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext-members.html +17 -14
  137. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext.html +69 -79
  138. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.map +3 -1
  139. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.md5 +1 -1
  140. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.png +0 -0
  141. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler-members.html +15 -12
  142. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler.html +60 -63
  143. data/doc/cxxapi/classPassenger_1_1Process-members.html +20 -17
  144. data/doc/cxxapi/classPassenger_1_1Process.html +88 -95
  145. data/doc/cxxapi/classPassenger_1_1RandomGenerator-members.html +13 -10
  146. data/doc/cxxapi/classPassenger_1_1RandomGenerator.html +36 -35
  147. data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +12 -9
  148. data/doc/cxxapi/classPassenger_1_1RuntimeException.html +24 -20
  149. data/doc/cxxapi/classPassenger_1_1ScalarMessage-members.html +37 -0
  150. data/doc/cxxapi/classPassenger_1_1ScalarMessage.html +76 -0
  151. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser-members.html +26 -23
  152. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser.html +121 -138
  153. data/doc/cxxapi/classPassenger_1_1SecurityException-members.html +12 -9
  154. data/doc/cxxapi/classPassenger_1_1SecurityException.html +26 -22
  155. data/doc/cxxapi/classPassenger_1_1Session-members.html +29 -26
  156. data/doc/cxxapi/classPassenger_1_1Session.html +219 -240
  157. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +14 -11
  158. data/doc/cxxapi/classPassenger_1_1SpawnException.html +36 -37
  159. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +18 -15
  160. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +115 -110
  161. data/doc/cxxapi/classPassenger_1_1StandardSession-members.html +30 -27
  162. data/doc/cxxapi/classPassenger_1_1StandardSession.html +163 -184
  163. data/doc/cxxapi/classPassenger_1_1StaticString-members.html +12 -9
  164. data/doc/cxxapi/classPassenger_1_1StaticString.html +27 -25
  165. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +16 -13
  166. data/doc/cxxapi/classPassenger_1_1SystemException.html +65 -67
  167. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException-members.html +16 -13
  168. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException.html +27 -23
  169. data/doc/cxxapi/classPassenger_1_1TimeoutException-members.html +12 -9
  170. data/doc/cxxapi/classPassenger_1_1TimeoutException.html +24 -20
  171. data/doc/cxxapi/classPassenger_1_1Uint16Message-members.html +36 -0
  172. data/doc/cxxapi/classPassenger_1_1Uint16Message.html +51 -0
  173. data/doc/cxxapi/classPassenger_1_1Uint32Message-members.html +36 -0
  174. data/doc/cxxapi/classPassenger_1_1Uint32Message.html +51 -0
  175. data/doc/cxxapi/classServer-members.html +12 -9
  176. data/doc/cxxapi/classServer.html +23 -20
  177. data/doc/cxxapi/classServerInstanceDirToucher-members.html +12 -9
  178. data/doc/cxxapi/classServerInstanceDirToucher.html +21 -17
  179. data/doc/cxxapi/classes.html +18 -4
  180. data/doc/cxxapi/definitions_8h_source.html +1 -0
  181. data/doc/cxxapi/files.html +36 -1
  182. data/doc/cxxapi/functions.html +53 -21
  183. data/doc/cxxapi/functions_0x62.html +82 -0
  184. data/doc/cxxapi/functions_0x63.html +99 -0
  185. data/doc/cxxapi/functions_0x64.html +95 -0
  186. data/doc/cxxapi/functions_0x65.html +88 -0
  187. data/doc/cxxapi/functions_0x66.html +100 -0
  188. data/doc/cxxapi/functions_0x67.html +170 -0
  189. data/doc/cxxapi/functions_0x68.html +88 -0
  190. data/doc/cxxapi/functions_0x69.html +93 -0
  191. data/doc/cxxapi/functions_0x6b.html +80 -0
  192. data/doc/cxxapi/functions_0x6c.html +88 -0
  193. data/doc/cxxapi/functions_0x6d.html +88 -0
  194. data/doc/cxxapi/functions_0x6e.html +86 -0
  195. data/doc/cxxapi/functions_0x6f.html +94 -0
  196. data/doc/cxxapi/functions_0x70.html +94 -0
  197. data/doc/cxxapi/functions_0x72.html +110 -0
  198. data/doc/cxxapi/functions_0x73.html +171 -0
  199. data/doc/cxxapi/functions_0x74.html +85 -0
  200. data/doc/cxxapi/functions_0x75.html +85 -0
  201. data/doc/cxxapi/functions_0x77.html +92 -0
  202. data/doc/cxxapi/functions_0x7e.html +79 -0
  203. data/doc/cxxapi/functions_enum.html +14 -12
  204. data/doc/cxxapi/functions_eval.html +22 -16
  205. data/doc/cxxapi/functions_func.html +460 -1
  206. data/doc/cxxapi/functions_vars.html +163 -63
  207. data/doc/cxxapi/graph_legend.html +1 -0
  208. data/doc/cxxapi/graph_legend.png +0 -0
  209. data/doc/cxxapi/group__Core.html +2 -2
  210. data/doc/cxxapi/group__Core.map +1 -2
  211. data/doc/cxxapi/group__Core.png +0 -0
  212. data/doc/cxxapi/group__Exceptions.html +32 -40
  213. data/doc/cxxapi/group__Hooks.html +2 -1
  214. data/doc/cxxapi/group__Hooks.map +1 -1
  215. data/doc/cxxapi/group__Hooks.png +0 -0
  216. data/doc/cxxapi/group__Support.html +509 -0
  217. data/doc/cxxapi/hierarchy.html +66 -62
  218. data/doc/cxxapi/inherit__graph__10.map +3 -1
  219. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  220. data/doc/cxxapi/inherit__graph__10.png +0 -0
  221. data/doc/cxxapi/inherit__graph__11.map +4 -1
  222. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  223. data/doc/cxxapi/inherit__graph__11.png +0 -0
  224. data/doc/cxxapi/inherit__graph__12.map +3 -1
  225. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  226. data/doc/cxxapi/inherit__graph__12.png +0 -0
  227. data/doc/cxxapi/inherit__graph__13.map +3 -1
  228. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  229. data/doc/cxxapi/inherit__graph__13.png +0 -0
  230. data/doc/cxxapi/inherit__graph__14.map +3 -1
  231. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  232. data/doc/cxxapi/inherit__graph__14.png +0 -0
  233. data/doc/cxxapi/inherit__graph__15.map +5 -1
  234. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  235. data/doc/cxxapi/inherit__graph__15.png +0 -0
  236. data/doc/cxxapi/inherit__graph__16.map +3 -3
  237. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  238. data/doc/cxxapi/inherit__graph__16.png +0 -0
  239. data/doc/cxxapi/inherit__graph__17.map +3 -1
  240. data/doc/cxxapi/inherit__graph__17.md5 +1 -1
  241. data/doc/cxxapi/inherit__graph__17.png +0 -0
  242. data/doc/cxxapi/inherit__graph__18.map +4 -1
  243. data/doc/cxxapi/inherit__graph__18.md5 +1 -1
  244. data/doc/cxxapi/inherit__graph__18.png +0 -0
  245. data/doc/cxxapi/inherit__graph__19.map +3 -1
  246. data/doc/cxxapi/inherit__graph__19.md5 +1 -1
  247. data/doc/cxxapi/inherit__graph__19.png +0 -0
  248. data/doc/cxxapi/inherit__graph__20.map +3 -2
  249. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  250. data/doc/cxxapi/inherit__graph__20.png +0 -0
  251. data/doc/cxxapi/inherit__graph__21.map +3 -1
  252. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  253. data/doc/cxxapi/inherit__graph__21.png +0 -0
  254. data/doc/cxxapi/inherit__graph__22.map +3 -1
  255. data/doc/cxxapi/inherit__graph__22.md5 +1 -1
  256. data/doc/cxxapi/inherit__graph__22.png +0 -0
  257. data/doc/cxxapi/inherit__graph__23.map +3 -1
  258. data/doc/cxxapi/inherit__graph__23.md5 +1 -1
  259. data/doc/cxxapi/inherit__graph__23.png +0 -0
  260. data/doc/cxxapi/inherit__graph__24.map +3 -1
  261. data/doc/cxxapi/inherit__graph__24.md5 +1 -1
  262. data/doc/cxxapi/inherit__graph__24.png +0 -0
  263. data/doc/cxxapi/inherit__graph__25.map +3 -1
  264. data/doc/cxxapi/inherit__graph__25.md5 +1 -1
  265. data/doc/cxxapi/inherit__graph__25.png +0 -0
  266. data/doc/cxxapi/inherit__graph__26.map +3 -1
  267. data/doc/cxxapi/inherit__graph__26.md5 +1 -1
  268. data/doc/cxxapi/inherit__graph__26.png +0 -0
  269. data/doc/cxxapi/inherit__graph__27.map +3 -1
  270. data/doc/cxxapi/inherit__graph__27.md5 +1 -1
  271. data/doc/cxxapi/inherit__graph__27.png +0 -0
  272. data/doc/cxxapi/inherit__graph__28.map +4 -1
  273. data/doc/cxxapi/inherit__graph__28.md5 +1 -1
  274. data/doc/cxxapi/inherit__graph__28.png +0 -0
  275. data/doc/cxxapi/inherit__graph__29.map +3 -1
  276. data/doc/cxxapi/inherit__graph__29.md5 +1 -1
  277. data/doc/cxxapi/inherit__graph__29.png +0 -0
  278. data/doc/cxxapi/inherit__graph__30.map +3 -2
  279. data/doc/cxxapi/inherit__graph__30.md5 +1 -1
  280. data/doc/cxxapi/inherit__graph__30.png +0 -0
  281. data/doc/cxxapi/inherit__graph__31.map +3 -1
  282. data/doc/cxxapi/inherit__graph__31.md5 +1 -1
  283. data/doc/cxxapi/inherit__graph__31.png +0 -0
  284. data/doc/cxxapi/inherit__graph__32.map +5 -1
  285. data/doc/cxxapi/inherit__graph__32.md5 +1 -1
  286. data/doc/cxxapi/inherit__graph__32.png +0 -0
  287. data/doc/cxxapi/inherit__graph__33.map +3 -1
  288. data/doc/cxxapi/inherit__graph__33.md5 +1 -1
  289. data/doc/cxxapi/inherit__graph__33.png +0 -0
  290. data/doc/cxxapi/inherit__graph__34.map +3 -3
  291. data/doc/cxxapi/inherit__graph__34.md5 +1 -1
  292. data/doc/cxxapi/inherit__graph__34.png +0 -0
  293. data/doc/cxxapi/inherit__graph__35.map +3 -1
  294. data/doc/cxxapi/inherit__graph__35.md5 +1 -1
  295. data/doc/cxxapi/inherit__graph__35.png +0 -0
  296. data/doc/cxxapi/inherit__graph__36.map +3 -1
  297. data/doc/cxxapi/inherit__graph__36.md5 +1 -1
  298. data/doc/cxxapi/inherit__graph__36.png +0 -0
  299. data/doc/cxxapi/inherit__graph__37.map +3 -1
  300. data/doc/cxxapi/inherit__graph__37.md5 +1 -1
  301. data/doc/cxxapi/inherit__graph__37.png +0 -0
  302. data/doc/cxxapi/inherit__graph__4.map +3 -1
  303. data/doc/cxxapi/inherit__graph__4.md5 +1 -1
  304. data/doc/cxxapi/inherit__graph__4.png +0 -0
  305. data/doc/cxxapi/inherit__graph__5.map +3 -1
  306. data/doc/cxxapi/inherit__graph__5.md5 +1 -1
  307. data/doc/cxxapi/inherit__graph__5.png +0 -0
  308. data/doc/cxxapi/inherit__graph__6.map +3 -1
  309. data/doc/cxxapi/inherit__graph__6.md5 +1 -1
  310. data/doc/cxxapi/inherit__graph__6.png +0 -0
  311. data/doc/cxxapi/inherit__graph__7.map +3 -1
  312. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  313. data/doc/cxxapi/inherit__graph__7.png +0 -0
  314. data/doc/cxxapi/inherit__graph__8.map +3 -1
  315. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  316. data/doc/cxxapi/inherit__graph__8.png +0 -0
  317. data/doc/cxxapi/inherit__graph__9.map +3 -1
  318. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  319. data/doc/cxxapi/inherit__graph__9.png +0 -0
  320. data/doc/cxxapi/inherits.html +123 -126
  321. data/doc/cxxapi/main.html +1 -0
  322. data/doc/cxxapi/modules.html +2 -1
  323. data/doc/cxxapi/namespacePassenger.html +263 -492
  324. data/doc/cxxapi/namespacemembers.html +68 -96
  325. data/doc/cxxapi/namespacemembers_enum.html +14 -12
  326. data/doc/cxxapi/namespacemembers_eval.html +20 -15
  327. data/doc/cxxapi/namespacemembers_func.html +52 -88
  328. data/doc/cxxapi/namespacemembers_type.html +18 -14
  329. data/doc/cxxapi/namespaces.html +12 -9
  330. data/doc/cxxapi/nginx_2Configuration_8h_source.html +125 -0
  331. data/doc/cxxapi/ngx__http__passenger__module_8h_source.html +94 -0
  332. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard-members.html +12 -9
  333. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard.html +24 -22
  334. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +43 -38
  335. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +275 -325
  336. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash-members.html +12 -9
  337. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash.html +24 -22
  338. data/doc/cxxapi/tree.html +152 -7
  339. data/doc/users_guide_snippets/{analysis_and_system_maintenance_tools.txt → analysis_and_system_maintenance.txt} +58 -1
  340. data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +1 -2
  341. data/doc/users_guide_snippets/global_queueing_explained.txt +1 -5
  342. data/doc/users_guide_snippets/{rails_spawn_method.txt → passenger_spawn_method.txt} +9 -8
  343. data/doc/users_guide_snippets/tips.txt +12 -6
  344. data/doc/users_guide_snippets/under_the_hood/page_caching_support.txt +22 -0
  345. data/ext/apache2/Bucket.cpp +4 -4
  346. data/ext/apache2/Bucket.h +3 -3
  347. data/ext/apache2/Configuration.cpp +278 -381
  348. data/ext/apache2/Configuration.h +3 -357
  349. data/ext/apache2/Configuration.hpp +461 -0
  350. data/ext/apache2/DirectoryMapper.h +3 -3
  351. data/ext/apache2/HelperAgent.cpp +359 -0
  352. data/ext/apache2/Hooks.cpp +339 -226
  353. data/ext/apache2/Hooks.h +1 -1
  354. data/ext/apache2/mod_passenger.c +10 -4
  355. data/ext/boost/algorithm/string/case_conv.hpp +4 -4
  356. data/ext/boost/algorithm/string/concept.hpp +2 -2
  357. data/ext/boost/algorithm/string/detail/case_conv.hpp +18 -9
  358. data/ext/boost/algorithm/string/detail/find_format.hpp +44 -43
  359. data/ext/boost/algorithm/string/detail/find_format_all.hpp +56 -56
  360. data/ext/boost/algorithm/string/detail/find_format_store.hpp +7 -0
  361. data/ext/boost/algorithm/string/detail/finder.hpp +14 -14
  362. data/ext/boost/algorithm/string/detail/formatter.hpp +2 -2
  363. data/ext/boost/algorithm/string/detail/replace_storage.hpp +3 -3
  364. data/ext/boost/algorithm/string/detail/sequence.hpp +3 -3
  365. data/ext/boost/algorithm/string/erase.hpp +98 -98
  366. data/ext/boost/algorithm/string/find_format.hpp +56 -38
  367. data/ext/boost/algorithm/string/finder.hpp +6 -6
  368. data/ext/boost/algorithm/string/formatter.hpp +1 -1
  369. data/ext/boost/algorithm/string/replace.hpp +99 -99
  370. data/ext/boost/bind.hpp +5 -1670
  371. data/ext/boost/bind/bind.hpp +1751 -0
  372. data/ext/boost/bind/bind_mf2_cc.hpp +228 -0
  373. data/ext/boost/bind/mem_fn.hpp +389 -0
  374. data/ext/boost/bind/mem_fn_template.hpp +54 -27
  375. data/ext/boost/bind/placeholders.hpp +3 -2
  376. data/ext/boost/concept_check.hpp +10 -0
  377. data/ext/boost/config/abi/msvc_prefix.hpp +15 -1
  378. data/ext/boost/config/abi_prefix.hpp +1 -1
  379. data/ext/boost/config/abi_suffix.hpp +3 -2
  380. data/ext/boost/config/auto_link.hpp +6 -1
  381. data/ext/boost/config/compiler/borland.hpp +75 -17
  382. data/ext/boost/config/compiler/codegear.hpp +163 -0
  383. data/ext/boost/config/compiler/common_edg.hpp +35 -0
  384. data/ext/boost/config/compiler/digitalmars.hpp +26 -0
  385. data/ext/boost/config/compiler/gcc.hpp +69 -14
  386. data/ext/boost/config/compiler/hp_acc.hpp +32 -0
  387. data/ext/boost/config/compiler/intel.hpp +13 -2
  388. data/ext/boost/config/compiler/kai.hpp +0 -2
  389. data/ext/boost/config/compiler/metrowerks.hpp +29 -1
  390. data/ext/boost/config/compiler/mpw.hpp +30 -0
  391. data/ext/boost/config/compiler/pgi.hpp +37 -0
  392. data/ext/boost/config/compiler/sgi_mipspro.hpp +1 -0
  393. data/ext/boost/config/compiler/sunpro_cc.hpp +39 -7
  394. data/ext/boost/config/compiler/vacpp.hpp +31 -3
  395. data/ext/boost/config/compiler/visualc.hpp +72 -5
  396. data/ext/boost/config/no_tr1/cmath.hpp +28 -0
  397. data/ext/boost/config/platform/bsd.hpp +16 -3
  398. data/ext/boost/config/platform/hpux.hpp +3 -0
  399. data/ext/boost/config/platform/macos.hpp +8 -0
  400. data/ext/boost/config/platform/solaris.hpp +7 -0
  401. data/ext/boost/config/platform/vxworks.hpp +31 -0
  402. data/ext/boost/config/select_compiler_config.hpp +4 -0
  403. data/ext/boost/config/select_platform_config.hpp +6 -2
  404. data/ext/boost/config/select_stdlib_config.hpp +17 -8
  405. data/ext/boost/config/stdlib/dinkumware.hpp +34 -2
  406. data/ext/boost/config/stdlib/libcomo.hpp +25 -0
  407. data/ext/boost/config/stdlib/libstdcpp3.hpp +56 -2
  408. data/ext/boost/config/stdlib/modena.hpp +25 -0
  409. data/ext/boost/config/stdlib/msl.hpp +24 -0
  410. data/ext/boost/config/stdlib/roguewave.hpp +26 -0
  411. data/ext/boost/config/stdlib/sgi.hpp +25 -0
  412. data/ext/boost/config/stdlib/stlport.hpp +36 -1
  413. data/ext/boost/config/stdlib/vacpp.hpp +25 -0
  414. data/ext/boost/config/suffix.hpp +67 -32
  415. data/ext/boost/config/warning_disable.hpp +47 -0
  416. data/ext/boost/cstdint.hpp +62 -36
  417. data/ext/boost/date_time/c_time.hpp +28 -12
  418. data/ext/boost/date_time/compiler_config.hpp +27 -5
  419. data/ext/boost/date_time/constrained_value.hpp +36 -13
  420. data/ext/boost/date_time/date.hpp +44 -33
  421. data/ext/boost/date_time/date_duration.hpp +13 -14
  422. data/ext/boost/date_time/date_facet.hpp +215 -226
  423. data/ext/boost/date_time/date_generator_formatter.hpp +22 -20
  424. data/ext/boost/date_time/date_generator_parser.hpp +52 -51
  425. data/ext/boost/date_time/date_generators.hpp +16 -16
  426. data/ext/boost/date_time/date_parsing.hpp +115 -98
  427. data/ext/boost/date_time/filetime_functions.hpp +133 -41
  428. data/ext/boost/date_time/format_date_parser.hpp +22 -10
  429. data/ext/boost/date_time/gregorian/conversion.hpp +32 -39
  430. data/ext/boost/date_time/gregorian/greg_calendar.hpp +15 -14
  431. data/ext/boost/date_time/gregorian/greg_date.hpp +19 -18
  432. data/ext/boost/date_time/gregorian/greg_duration.hpp +106 -10
  433. data/ext/boost/date_time/gregorian/greg_duration_types.hpp +16 -7
  434. data/ext/boost/date_time/gregorian/greg_weekday.hpp +2 -2
  435. data/ext/boost/date_time/gregorian/gregorian_io.hpp +11 -4
  436. data/ext/boost/date_time/gregorian_calendar.hpp +8 -8
  437. data/ext/boost/date_time/gregorian_calendar.ipp +30 -30
  438. data/ext/boost/date_time/int_adapter.hpp +4 -2
  439. data/ext/boost/date_time/microsec_time_clock.hpp +39 -117
  440. data/ext/boost/date_time/period_parser.hpp +17 -15
  441. data/ext/boost/date_time/posix_time/conversion.hpp +28 -29
  442. data/ext/boost/date_time/posix_time/posix_time_config.hpp +19 -19
  443. data/ext/boost/date_time/posix_time/posix_time_io.hpp +31 -38
  444. data/ext/boost/date_time/posix_time/time_formatters.hpp +32 -32
  445. data/ext/boost/date_time/string_parse_tree.hpp +46 -46
  446. data/ext/boost/date_time/strings_from_facet.hpp +7 -5
  447. data/ext/boost/date_time/time.hpp +7 -6
  448. data/ext/boost/date_time/time_defs.hpp +12 -2
  449. data/ext/boost/date_time/time_duration.hpp +27 -26
  450. data/ext/boost/date_time/time_facet.hpp +386 -321
  451. data/ext/boost/date_time/time_formatting_streams.hpp +8 -5
  452. data/ext/boost/date_time/time_resolution_traits.hpp +29 -25
  453. data/ext/boost/date_time/time_system_split.hpp +7 -13
  454. data/ext/boost/date_time/wrapping_int.hpp +21 -15
  455. data/ext/boost/detail/call_traits.hpp +1 -1
  456. data/ext/boost/detail/endian.hpp +4 -4
  457. data/ext/boost/detail/no_exceptions_support.hpp +87 -0
  458. data/ext/boost/detail/sp_typeinfo.hpp +50 -4
  459. data/ext/boost/detail/workaround.hpp +63 -3
  460. data/ext/boost/enable_shared_from_this.hpp +4 -59
  461. data/ext/boost/exception/current_exception_cast.hpp +43 -0
  462. data/ext/boost/exception/detail/attribute_noreturn.hpp +17 -0
  463. data/ext/boost/exception/detail/error_info_impl.hpp +75 -0
  464. data/ext/boost/exception/detail/exception_ptr.hpp +490 -0
  465. data/ext/boost/exception/detail/is_output_streamable.hpp +47 -0
  466. data/ext/boost/exception/detail/object_hex_dump.hpp +50 -0
  467. data/ext/boost/exception/detail/type_info.hpp +79 -0
  468. data/ext/boost/exception/diagnostic_information.hpp +182 -0
  469. data/ext/boost/exception/exception.hpp +422 -0
  470. data/ext/boost/exception/get_error_info.hpp +130 -0
  471. data/ext/boost/exception/info.hpp +167 -0
  472. data/ext/boost/exception/to_string.hpp +83 -0
  473. data/ext/boost/exception/to_string_stub.hpp +109 -0
  474. data/ext/boost/exception_ptr.hpp +11 -0
  475. data/ext/boost/function/detail/prologue.hpp +2 -1
  476. data/ext/boost/function/function_base.hpp +270 -128
  477. data/ext/boost/function/function_fwd.hpp +70 -0
  478. data/ext/boost/function/function_template.hpp +319 -130
  479. data/ext/boost/get_pointer.hpp +5 -1
  480. data/ext/boost/integer.hpp +253 -0
  481. data/ext/boost/integer_fwd.hpp +174 -0
  482. data/ext/boost/integer_traits.hpp +26 -1
  483. data/ext/boost/io/ios_state.hpp +8 -0
  484. data/ext/boost/iterator/detail/config_def.hpp +4 -2
  485. data/ext/boost/iterator/iterator_adaptor.hpp +7 -2
  486. data/ext/boost/iterator/iterator_facade.hpp +1 -2
  487. data/ext/boost/lexical_cast.hpp +113 -105
  488. data/ext/boost/limits.hpp +1 -1
  489. data/ext/boost/mem_fn.hpp +5 -370
  490. data/ext/boost/memory_order.hpp +53 -0
  491. data/ext/boost/mpl/always.hpp +3 -3
  492. data/ext/boost/mpl/and.hpp +3 -3
  493. data/ext/boost/mpl/apply.hpp +3 -3
  494. data/ext/boost/mpl/apply_fwd.hpp +3 -3
  495. data/ext/boost/mpl/apply_wrap.hpp +37 -6
  496. data/ext/boost/mpl/arg.hpp +3 -3
  497. data/ext/boost/mpl/arg_fwd.hpp +3 -3
  498. data/ext/boost/mpl/assert.hpp +6 -6
  499. data/ext/boost/mpl/aux_/adl_barrier.hpp +3 -3
  500. data/ext/boost/mpl/aux_/arg_typedef.hpp +3 -3
  501. data/ext/boost/mpl/aux_/arity.hpp +3 -3
  502. data/ext/boost/mpl/aux_/arity_spec.hpp +3 -3
  503. data/ext/boost/mpl/aux_/common_name_wknd.hpp +3 -3
  504. data/ext/boost/mpl/aux_/config/adl.hpp +4 -4
  505. data/ext/boost/mpl/aux_/config/arrays.hpp +4 -4
  506. data/ext/boost/mpl/aux_/config/bcc.hpp +28 -0
  507. data/ext/boost/mpl/aux_/config/bind.hpp +4 -4
  508. data/ext/boost/mpl/aux_/config/compiler.hpp +8 -6
  509. data/ext/boost/mpl/aux_/config/ctps.hpp +3 -3
  510. data/ext/boost/mpl/aux_/config/dtp.hpp +5 -5
  511. data/ext/boost/mpl/aux_/config/eti.hpp +3 -3
  512. data/ext/boost/mpl/aux_/config/gcc.hpp +3 -3
  513. data/ext/boost/mpl/aux_/config/has_apply.hpp +3 -3
  514. data/ext/boost/mpl/aux_/config/has_xxx.hpp +3 -3
  515. data/ext/boost/mpl/aux_/config/integral.hpp +4 -4
  516. data/ext/boost/mpl/aux_/config/intel.hpp +3 -3
  517. data/ext/boost/mpl/aux_/config/lambda.hpp +3 -3
  518. data/ext/boost/mpl/aux_/config/msvc.hpp +3 -3
  519. data/ext/boost/mpl/aux_/config/msvc_typename.hpp +3 -3
  520. data/ext/boost/mpl/aux_/config/nttp.hpp +3 -3
  521. data/ext/boost/mpl/aux_/config/overload_resolution.hpp +3 -3
  522. data/ext/boost/mpl/aux_/config/pp_counter.hpp +3 -3
  523. data/ext/boost/mpl/aux_/config/preprocessor.hpp +4 -4
  524. data/ext/boost/mpl/aux_/config/static_constant.hpp +3 -3
  525. data/ext/boost/mpl/aux_/config/ttp.hpp +4 -4
  526. data/ext/boost/mpl/aux_/config/use_preprocessed.hpp +3 -3
  527. data/ext/boost/mpl/aux_/config/workaround.hpp +3 -3
  528. data/ext/boost/mpl/aux_/full_lambda.hpp +3 -3
  529. data/ext/boost/mpl/aux_/has_apply.hpp +3 -3
  530. data/ext/boost/mpl/aux_/has_type.hpp +3 -3
  531. data/ext/boost/mpl/aux_/include_preprocessed.hpp +3 -3
  532. data/ext/boost/mpl/aux_/integral_wrapper.hpp +3 -3
  533. data/ext/boost/mpl/aux_/lambda_arity_param.hpp +3 -3
  534. data/ext/boost/mpl/aux_/lambda_support.hpp +4 -4
  535. data/ext/boost/mpl/aux_/msvc_never_true.hpp +3 -3
  536. data/ext/boost/mpl/aux_/na.hpp +3 -3
  537. data/ext/boost/mpl/aux_/na_assert.hpp +3 -3
  538. data/ext/boost/mpl/aux_/na_fwd.hpp +3 -3
  539. data/ext/boost/mpl/aux_/na_spec.hpp +3 -3
  540. data/ext/boost/mpl/aux_/nested_type_wknd.hpp +3 -3
  541. data/ext/boost/mpl/aux_/nttp_decl.hpp +3 -3
  542. data/ext/boost/mpl/aux_/preprocessor/def_params_tail.hpp +3 -3
  543. data/ext/boost/mpl/aux_/preprocessor/enum.hpp +3 -3
  544. data/ext/boost/mpl/aux_/preprocessor/filter_params.hpp +3 -3
  545. data/ext/boost/mpl/aux_/preprocessor/params.hpp +3 -3
  546. data/ext/boost/mpl/aux_/preprocessor/sub.hpp +3 -3
  547. data/ext/boost/mpl/aux_/static_cast.hpp +3 -3
  548. data/ext/boost/mpl/aux_/template_arity.hpp +3 -3
  549. data/ext/boost/mpl/aux_/template_arity_fwd.hpp +3 -3
  550. data/ext/boost/mpl/aux_/type_wrapper.hpp +3 -3
  551. data/ext/boost/mpl/aux_/value_wknd.hpp +3 -3
  552. data/ext/boost/mpl/aux_/yes_no.hpp +3 -3
  553. data/ext/boost/mpl/bind.hpp +3 -3
  554. data/ext/boost/mpl/bind_fwd.hpp +3 -3
  555. data/ext/boost/mpl/bool.hpp +3 -3
  556. data/ext/boost/mpl/bool_fwd.hpp +3 -3
  557. data/ext/boost/mpl/eval_if.hpp +3 -3
  558. data/ext/boost/mpl/has_xxx.hpp +10 -8
  559. data/ext/boost/mpl/identity.hpp +3 -3
  560. data/ext/boost/mpl/if.hpp +3 -3
  561. data/ext/boost/mpl/int.hpp +3 -3
  562. data/ext/boost/mpl/int_fwd.hpp +3 -3
  563. data/ext/boost/mpl/integral_c.hpp +3 -3
  564. data/ext/boost/mpl/integral_c_fwd.hpp +3 -3
  565. data/ext/boost/mpl/integral_c_tag.hpp +3 -3
  566. data/ext/boost/mpl/lambda.hpp +3 -3
  567. data/ext/boost/mpl/lambda_fwd.hpp +3 -3
  568. data/ext/boost/mpl/limits/arity.hpp +3 -3
  569. data/ext/boost/mpl/logical.hpp +3 -3
  570. data/ext/boost/mpl/next.hpp +3 -3
  571. data/ext/boost/mpl/next_prior.hpp +3 -3
  572. data/ext/boost/mpl/not.hpp +3 -3
  573. data/ext/boost/mpl/or.hpp +3 -3
  574. data/ext/boost/mpl/placeholders.hpp +3 -3
  575. data/ext/boost/mpl/protect.hpp +3 -3
  576. data/ext/boost/mpl/quote.hpp +18 -7
  577. data/ext/boost/mpl/size_t.hpp +3 -3
  578. data/ext/boost/mpl/size_t_fwd.hpp +3 -3
  579. data/ext/boost/mpl/void.hpp +3 -3
  580. data/ext/boost/mpl/void_fwd.hpp +3 -3
  581. data/ext/boost/non_type.hpp +27 -27
  582. data/ext/boost/operators.hpp +51 -18
  583. data/ext/boost/preprocessor/arithmetic/detail/div_base.hpp +61 -0
  584. data/ext/boost/preprocessor/arithmetic/mod.hpp +39 -0
  585. data/ext/boost/preprocessor/comparison/less_equal.hpp +39 -0
  586. data/ext/boost/preprocessor/control/deduce_d.hpp +22 -0
  587. data/ext/boost/preprocessor/logical/not.hpp +30 -0
  588. data/ext/boost/preprocessor/seq/cat.hpp +48 -0
  589. data/ext/boost/preprocessor/seq/fold_left.hpp +1070 -0
  590. data/ext/boost/preprocessor/seq/transform.hpp +48 -0
  591. data/ext/boost/range/as_literal.hpp +10 -14
  592. data/ext/boost/range/begin.hpp +4 -4
  593. data/ext/boost/range/detail/implementation_help.hpp +4 -0
  594. data/ext/boost/range/end.hpp +4 -4
  595. data/ext/boost/range/iterator_range.hpp +31 -15
  596. data/ext/boost/ref.hpp +12 -1
  597. data/ext/boost/scoped_array.hpp +16 -0
  598. data/ext/boost/scoped_ptr.hpp +16 -0
  599. data/ext/boost/shared_ptr.hpp +2 -602
  600. data/ext/boost/{detail → smart_ptr}/bad_weak_ptr.hpp +4 -4
  601. data/ext/boost/{detail → smart_ptr/detail}/atomic_count.hpp +14 -19
  602. data/ext/boost/{detail → smart_ptr/detail}/atomic_count_gcc.hpp +13 -9
  603. data/ext/boost/{detail → smart_ptr/detail}/atomic_count_gcc_x86.hpp +5 -12
  604. data/ext/boost/{detail → smart_ptr/detail}/atomic_count_pthreads.hpp +5 -5
  605. data/ext/boost/{detail → smart_ptr/detail}/atomic_count_solaris.hpp +3 -3
  606. data/ext/boost/{detail → smart_ptr/detail}/atomic_count_sync.hpp +9 -5
  607. data/ext/boost/{detail → smart_ptr/detail}/atomic_count_win32.hpp +3 -3
  608. data/ext/boost/smart_ptr/detail/operator_bool.hpp +56 -0
  609. data/ext/boost/{detail → smart_ptr/detail}/shared_count.hpp +86 -17
  610. data/ext/boost/smart_ptr/detail/sp_convertible.hpp +76 -0
  611. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +70 -0
  612. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_acc_ia64.hpp +4 -4
  613. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_cw_ppc.hpp +4 -4
  614. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_cw_x86.hpp +4 -4
  615. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_ia64.hpp +4 -4
  616. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +172 -0
  617. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_ppc.hpp +4 -4
  618. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_sparc.hpp +7 -7
  619. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_gcc_x86.hpp +4 -4
  620. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_nt.hpp +4 -4
  621. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_pt.hpp +4 -4
  622. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_solaris.hpp +4 -4
  623. data/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp +131 -0
  624. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_sync.hpp +8 -4
  625. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_base_w32.hpp +4 -4
  626. data/ext/boost/{detail → smart_ptr/detail}/sp_counted_impl.hpp +5 -5
  627. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +49 -0
  628. data/ext/boost/smart_ptr/detail/spinlock.hpp +53 -0
  629. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +85 -0
  630. data/ext/boost/smart_ptr/detail/spinlock_nt.hpp +89 -0
  631. data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +87 -0
  632. data/ext/boost/smart_ptr/detail/spinlock_pt.hpp +79 -0
  633. data/ext/boost/smart_ptr/detail/spinlock_sync.hpp +87 -0
  634. data/ext/boost/smart_ptr/detail/yield_k.hpp +149 -0
  635. data/ext/boost/smart_ptr/enable_shared_from_this.hpp +79 -0
  636. data/ext/boost/smart_ptr/scoped_array.hpp +107 -0
  637. data/ext/boost/smart_ptr/scoped_ptr.hpp +131 -0
  638. data/ext/boost/smart_ptr/shared_ptr.hpp +701 -0
  639. data/ext/boost/smart_ptr/weak_ptr.hpp +230 -0
  640. data/ext/boost/src/pthread/thread.cpp +115 -203
  641. data/ext/boost/src/tss_null.cpp +1 -1
  642. data/ext/boost/static_assert.hpp +14 -4
  643. data/ext/boost/thread.hpp +7 -2
  644. data/ext/boost/thread/barrier.hpp +63 -0
  645. data/ext/boost/thread/detail/force_cast.hpp +39 -0
  646. data/ext/boost/thread/detail/move.hpp +29 -2
  647. data/ext/boost/thread/detail/platform.hpp +3 -3
  648. data/ext/boost/thread/detail/singleton.hpp +59 -0
  649. data/ext/boost/thread/detail/thread.hpp +496 -0
  650. data/ext/boost/thread/detail/thread_group.hpp +105 -0
  651. data/ext/boost/thread/detail/thread_heap_alloc.hpp +23 -0
  652. data/ext/boost/thread/detail/thread_interruption.hpp +35 -0
  653. data/ext/boost/thread/detail/tss_hooks.hpp +82 -0
  654. data/ext/boost/thread/exceptions.hpp +174 -60
  655. data/ext/boost/thread/future.hpp +1364 -0
  656. data/ext/boost/thread/locks.hpp +899 -32
  657. data/ext/boost/thread/once.hpp +4 -0
  658. data/ext/boost/thread/pthread/condition_variable.hpp +16 -21
  659. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +37 -3
  660. data/ext/boost/thread/pthread/mutex.hpp +20 -7
  661. data/ext/boost/thread/pthread/once.hpp +7 -2
  662. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +5 -1
  663. data/ext/boost/thread/pthread/recursive_mutex.hpp +22 -5
  664. data/ext/boost/thread/pthread/shared_mutex.hpp +303 -0
  665. data/ext/boost/thread/pthread/thread_data.hpp +37 -10
  666. data/ext/boost/thread/pthread/thread_heap_alloc.hpp +242 -0
  667. data/ext/boost/thread/pthread/timespec.hpp +11 -3
  668. data/ext/boost/thread/shared_mutex.hpp +21 -0
  669. data/ext/boost/thread/thread.hpp +8 -3
  670. data/ext/boost/thread/thread_time.hpp +4 -0
  671. data/ext/boost/thread/tss.hpp +106 -13
  672. data/ext/boost/thread/xtime.hpp +6 -2
  673. data/ext/boost/throw_exception.hpp +36 -7
  674. data/ext/boost/token_functions.hpp +1 -1
  675. data/ext/boost/tokenizer.hpp +1 -1
  676. data/ext/boost/type_traits/add_pointer.hpp +1 -1
  677. data/ext/boost/type_traits/add_volatile.hpp +47 -0
  678. data/ext/boost/type_traits/alignment_of.hpp +29 -1
  679. data/ext/boost/type_traits/config.hpp +1 -1
  680. data/ext/boost/type_traits/conversion_traits.hpp +1 -1
  681. data/ext/boost/type_traits/has_trivial_destructor.hpp +42 -0
  682. data/ext/boost/type_traits/intrinsics.hpp +88 -1
  683. data/ext/boost/type_traits/is_abstract.hpp +14 -5
  684. data/ext/boost/type_traits/is_arithmetic.hpp +8 -0
  685. data/ext/boost/type_traits/is_array.hpp +3 -2
  686. data/ext/boost/type_traits/is_base_and_derived.hpp +254 -0
  687. data/ext/boost/type_traits/is_base_of.hpp +51 -0
  688. data/ext/boost/type_traits/is_class.hpp +12 -0
  689. data/ext/boost/type_traits/is_const.hpp +6 -2
  690. data/ext/boost/type_traits/is_convertible.hpp +14 -2
  691. data/ext/boost/type_traits/is_enum.hpp +10 -1
  692. data/ext/boost/type_traits/is_function.hpp +11 -3
  693. data/ext/boost/type_traits/is_fundamental.hpp +45 -0
  694. data/ext/boost/type_traits/is_integral.hpp +5 -0
  695. data/ext/boost/type_traits/is_member_function_pointer.hpp +5 -3
  696. data/ext/boost/type_traits/is_member_pointer.hpp +4 -2
  697. data/ext/boost/type_traits/is_pointer.hpp +3 -1
  698. data/ext/boost/type_traits/is_reference.hpp +4 -2
  699. data/ext/boost/type_traits/is_signed.hpp +135 -0
  700. data/ext/boost/type_traits/is_unsigned.hpp +130 -0
  701. data/ext/boost/type_traits/is_void.hpp +5 -0
  702. data/ext/boost/type_traits/is_volatile.hpp +4 -2
  703. data/ext/boost/type_traits/make_unsigned.hpp +137 -0
  704. data/ext/boost/type_traits/remove_reference.hpp +1 -1
  705. data/ext/boost/type_traits/type_with_alignment.hpp +106 -1
  706. data/ext/boost/utility.hpp +2 -1
  707. data/ext/boost/utility/addressof.hpp +61 -17
  708. data/ext/boost/utility/binary.hpp +708 -0
  709. data/ext/boost/utility/enable_if.hpp +2 -2
  710. data/ext/boost/weak_ptr.hpp +4 -174
  711. data/ext/common/AbstractSpawnManager.h +110 -0
  712. data/ext/common/Account.h +175 -0
  713. data/ext/common/AccountsDatabase.cpp +81 -0
  714. data/ext/common/AccountsDatabase.h +130 -0
  715. data/ext/common/AgentBase.cpp +323 -0
  716. data/ext/common/{Version.h → AgentBase.h} +14 -6
  717. data/ext/common/AgentsStarter.cpp +154 -0
  718. data/ext/common/AgentsStarter.h +81 -0
  719. data/ext/common/AgentsStarter.hpp +619 -0
  720. data/ext/common/ApplicationPool/Client.h +796 -0
  721. data/ext/common/{ApplicationPool.h → ApplicationPool/Interface.h} +108 -18
  722. data/ext/common/ApplicationPool/Pool.h +1315 -0
  723. data/ext/common/ApplicationPool/Server.h +475 -0
  724. data/ext/common/BCrypt.cpp +343 -0
  725. data/ext/common/BCrypt.h +73 -0
  726. data/ext/common/Blowfish.c +685 -0
  727. data/ext/common/Blowfish.h +103 -0
  728. data/ext/common/Constants.h +48 -0
  729. data/ext/common/EventedClient.h +598 -0
  730. data/ext/common/EventedMessageServer.h +327 -0
  731. data/ext/common/EventedServer.h +295 -0
  732. data/ext/common/Exceptions.h +78 -1
  733. data/ext/common/FileDescriptor.h +229 -0
  734. data/ext/common/HelperAgent/BacktracesServer.h +59 -0
  735. data/ext/common/Logging.cpp +8 -9
  736. data/ext/common/Logging.h +593 -21
  737. data/ext/common/LoggingAgent/ChangeNotifier.h +63 -0
  738. data/ext/common/LoggingAgent/DataStoreId.h +177 -0
  739. data/ext/common/LoggingAgent/LoggingServer.h +1343 -0
  740. data/ext/common/LoggingAgent/Main.cpp +278 -0
  741. data/ext/common/LoggingAgent/RemoteSender.h +457 -0
  742. data/ext/common/MessageChannel.h +196 -34
  743. data/ext/common/MessageClient.h +297 -0
  744. data/ext/common/MessageReadersWriters.h +508 -0
  745. data/ext/common/MessageServer.h +575 -0
  746. data/ext/common/PoolOptions.h +279 -117
  747. data/ext/common/Process.h +255 -0
  748. data/ext/common/RandomGenerator.h +160 -0
  749. data/ext/common/ResourceLocator.h +84 -0
  750. data/ext/common/ServerInstanceDir.h +343 -0
  751. data/ext/common/Session.h +470 -0
  752. data/ext/common/SpawnManager.h +256 -201
  753. data/ext/common/StaticString.h +79 -4
  754. data/ext/common/StringListCreator.h +2 -2
  755. data/ext/common/Utils.cpp +385 -397
  756. data/ext/common/Utils.h +79 -165
  757. data/ext/common/{Base64.cpp → Utils/Base64.cpp} +0 -0
  758. data/ext/common/{Base64.h → Utils/Base64.h} +27 -1
  759. data/ext/common/Utils/BlockingQueue.h +136 -0
  760. data/ext/common/Utils/BlockingScalar.h +50 -0
  761. data/ext/common/{CachedFileStat.cpp → Utils/CachedFileStat.cpp} +1 -1
  762. data/ext/common/{CachedFileStat.h → Utils/CachedFileStat.h} +1 -1
  763. data/ext/common/{CachedFileStat.hpp → Utils/CachedFileStat.hpp} +1 -1
  764. data/ext/common/{FileChangeChecker.h → Utils/FileChangeChecker.h} +1 -1
  765. data/ext/common/Utils/FileHandleGuard.h +81 -0
  766. data/ext/common/Utils/IOUtils.cpp +754 -0
  767. data/ext/common/Utils/IOUtils.h +253 -0
  768. data/ext/common/Utils/MD5.cpp +406 -0
  769. data/ext/common/Utils/MD5.h +98 -0
  770. data/ext/common/Utils/MemZeroGuard.h +103 -0
  771. data/ext/common/Utils/ProcessMetricsCollector.h +462 -0
  772. data/ext/common/Utils/ScopeGuard.h +72 -0
  773. data/ext/common/Utils/StrIntUtils.cpp +329 -0
  774. data/ext/common/Utils/StrIntUtils.h +228 -0
  775. data/ext/common/{SystemTime.cpp → Utils/SystemTime.cpp} +5 -1
  776. data/ext/common/Utils/SystemTime.h +201 -0
  777. data/ext/common/{Timer.h → Utils/Timer.h} +58 -18
  778. data/ext/common/Utils/VariantMap.h +363 -0
  779. data/ext/common/Utils/foo.cpp +10 -0
  780. data/ext/common/Watchdog.cpp +1034 -0
  781. data/ext/google/COPYING +28 -0
  782. data/ext/google/ChangeLog +167 -0
  783. data/ext/google/dense_hash_map +310 -0
  784. data/ext/google/dense_hash_set +287 -0
  785. data/ext/google/sparse_hash_map +294 -0
  786. data/ext/google/sparse_hash_set +275 -0
  787. data/ext/google/sparsehash/densehashtable.h +1062 -0
  788. data/ext/google/sparsehash/sparseconfig.h +55 -0
  789. data/ext/google/sparsehash/sparsehashtable.h +1015 -0
  790. data/ext/google/sparsetable +1468 -0
  791. data/ext/google/type_traits.h +250 -0
  792. data/ext/libev/Changes +302 -0
  793. data/ext/libev/LICENSE +36 -0
  794. data/ext/libev/Makefile.am +18 -0
  795. data/ext/libev/Makefile.in +685 -0
  796. data/ext/libev/README +58 -0
  797. data/ext/libev/aclocal.m4 +7549 -0
  798. data/ext/libev/autogen.sh +6 -0
  799. data/ext/libev/config.guess +1526 -0
  800. data/ext/libev/config.h +122 -0
  801. data/ext/libev/config.h.in +121 -0
  802. data/ext/libev/config.sub +1658 -0
  803. data/ext/libev/configure +22156 -0
  804. data/ext/libev/configure.ac +18 -0
  805. data/ext/libev/ev++.h +800 -0
  806. data/ext/libev/ev.c +3694 -0
  807. data/ext/libev/ev.h +705 -0
  808. data/ext/libev/ev_epoll.c +228 -0
  809. data/ext/libev/ev_kqueue.c +196 -0
  810. data/ext/libev/ev_poll.c +144 -0
  811. data/ext/libev/ev_port.c +165 -0
  812. data/ext/libev/ev_select.c +308 -0
  813. data/ext/libev/ev_vars.h +187 -0
  814. data/ext/libev/ev_win32.c +153 -0
  815. data/ext/libev/ev_wrap.h +178 -0
  816. data/ext/libev/event.c +401 -0
  817. data/ext/libev/event.h +158 -0
  818. data/ext/libev/install-sh +294 -0
  819. data/ext/libev/libev.m4 +38 -0
  820. data/ext/libev/ltmain.sh +6871 -0
  821. data/ext/libev/missing +336 -0
  822. data/ext/libev/mkinstalldirs +111 -0
  823. data/ext/nginx/Configuration.c +532 -182
  824. data/ext/nginx/Configuration.h +33 -10
  825. data/ext/nginx/ContentHandler.c +188 -53
  826. data/ext/nginx/ContentHandler.h +1 -1
  827. data/ext/nginx/{HelperServer.cpp → HelperAgent.cpp} +433 -299
  828. data/ext/nginx/HttpStatusExtractor.h +1 -1
  829. data/ext/nginx/ScgiRequestParser.h +68 -11
  830. data/ext/nginx/StaticContentHandler.c +4 -1
  831. data/ext/nginx/StaticContentHandler.h +1 -1
  832. data/ext/nginx/config +5 -5
  833. data/ext/nginx/ngx_http_passenger_module.c +315 -469
  834. data/ext/nginx/ngx_http_passenger_module.h +8 -17
  835. data/ext/oxt/backtrace.cpp +49 -41
  836. data/ext/oxt/backtrace.hpp +1 -1
  837. data/ext/oxt/detail/backtrace_disabled.hpp +1 -1
  838. data/ext/oxt/detail/backtrace_enabled.hpp +16 -15
  839. data/ext/oxt/detail/spin_lock_darwin.hpp +69 -0
  840. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -4
  841. data/ext/oxt/detail/spin_lock_portable.hpp +1 -1
  842. data/ext/oxt/detail/spin_lock_pthreads.hpp +1 -1
  843. data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
  844. data/ext/oxt/detail/tracable_exception_enabled.hpp +1 -1
  845. data/ext/oxt/dynamic_thread_group.hpp +195 -0
  846. data/ext/oxt/macros.hpp +1 -1
  847. data/ext/oxt/spin_lock.hpp +4 -2
  848. data/ext/oxt/system_calls.cpp +129 -13
  849. data/ext/oxt/system_calls.hpp +16 -2
  850. data/ext/oxt/thread.cpp +1 -1
  851. data/ext/oxt/thread.hpp +49 -14
  852. data/ext/oxt/tracable_exception.cpp +5 -5
  853. data/ext/oxt/tracable_exception.hpp +1 -1
  854. data/ext/phusion_passenger/extconf.rb +7 -2
  855. data/ext/phusion_passenger/native_support.c +733 -33
  856. data/{bin → helper-scripts}/passenger-spawn-server +50 -12
  857. data/helper-scripts/prespawn +63 -0
  858. data/lib/phusion_passenger.rb +113 -0
  859. data/lib/phusion_passenger/abstract_installer.rb +50 -12
  860. data/lib/phusion_passenger/abstract_request_handler.rb +432 -171
  861. data/lib/phusion_passenger/abstract_server.rb +125 -122
  862. data/lib/phusion_passenger/abstract_server_collection.rb +51 -22
  863. data/lib/phusion_passenger/admin_tools.rb +1 -1
  864. data/lib/phusion_passenger/admin_tools/memory_stats.rb +299 -0
  865. data/lib/phusion_passenger/admin_tools/server_instance.rb +334 -0
  866. data/lib/phusion_passenger/analytics_logger.rb +342 -0
  867. data/lib/phusion_passenger/{application.rb → app_process.rb} +73 -24
  868. data/lib/phusion_passenger/classic_rails/application_spawner.rb +344 -0
  869. data/lib/phusion_passenger/{railz → classic_rails}/cgi_fixed.rb +2 -2
  870. data/lib/phusion_passenger/{railz → classic_rails}/framework_spawner.rb +75 -98
  871. data/lib/phusion_passenger/{railz → classic_rails}/request_handler.rb +8 -6
  872. data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_base_extension.rb +65 -0
  873. data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_benchmarking_extension.rb +48 -0
  874. data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_rescue_extension.rb +59 -0
  875. data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ar_abstract_adapter_extension.rb +54 -0
  876. data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/as_cache_extension.rb +130 -0
  877. data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/av_benchmark_helper_extension.rb +47 -0
  878. data/lib/phusion_passenger/classic_rails_extensions/init.rb +123 -0
  879. data/lib/phusion_passenger/console_text_template.rb +1 -1
  880. data/lib/phusion_passenger/constants.rb +9 -5
  881. data/lib/phusion_passenger/debug_logging.rb +104 -0
  882. data/lib/phusion_passenger/dependencies.rb +187 -4
  883. data/lib/phusion_passenger/exceptions.rb +4 -4
  884. data/lib/phusion_passenger/html_template.rb +6 -8
  885. data/lib/phusion_passenger/message_channel.rb +137 -21
  886. data/lib/phusion_passenger/message_client.rb +173 -0
  887. data/lib/phusion_passenger/native_support.rb +108 -0
  888. data/lib/phusion_passenger/packaging.rb +82 -13
  889. data/lib/phusion_passenger/platform_info.rb +84 -475
  890. data/lib/phusion_passenger/platform_info/apache.rb +329 -0
  891. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +187 -0
  892. data/lib/phusion_passenger/platform_info/compiler.rb +154 -0
  893. data/lib/phusion_passenger/{events.rb → platform_info/curl.rb} +26 -23
  894. data/lib/phusion_passenger/platform_info/documentation_tools.rb +35 -0
  895. data/lib/phusion_passenger/platform_info/linux.rb +77 -0
  896. data/lib/phusion_passenger/platform_info/operating_system.rb +51 -0
  897. data/lib/phusion_passenger/platform_info/ruby.rb +198 -0
  898. data/lib/phusion_passenger/platform_info/zlib.rb +38 -0
  899. data/lib/phusion_passenger/plugin.rb +96 -0
  900. data/lib/phusion_passenger/public_api.rb +112 -0
  901. data/lib/phusion_passenger/rack/application_spawner.rb +146 -71
  902. data/lib/phusion_passenger/rack/request_handler.rb +36 -13
  903. data/lib/phusion_passenger/rails3_extensions/init.rb +204 -0
  904. data/lib/phusion_passenger/simple_benchmarking.rb +1 -1
  905. data/lib/phusion_passenger/spawn_manager.rb +137 -141
  906. data/lib/phusion_passenger/standalone/app_finder.rb +153 -0
  907. data/lib/phusion_passenger/standalone/command.rb +237 -0
  908. data/lib/phusion_passenger/standalone/config_file.rb +119 -0
  909. data/lib/phusion_passenger/standalone/help_command.rb +57 -0
  910. data/lib/phusion_passenger/standalone/main.rb +101 -0
  911. data/lib/phusion_passenger/standalone/package_runtime_command.rb +92 -0
  912. data/lib/phusion_passenger/standalone/runtime_installer.rb +466 -0
  913. data/lib/phusion_passenger/standalone/start_command.rb +510 -0
  914. data/lib/phusion_passenger/standalone/status_command.rb +62 -0
  915. data/lib/phusion_passenger/standalone/stop_command.rb +74 -0
  916. data/lib/phusion_passenger/standalone/utils.rb +42 -0
  917. data/lib/phusion_passenger/standalone/version_command.rb +42 -0
  918. data/lib/phusion_passenger/templates/framework_init_error.html.erb +1 -1
  919. data/lib/phusion_passenger/templates/standalone/cannot_write_to_dir.txt.erb +11 -0
  920. data/lib/phusion_passenger/templates/standalone/config.erb +69 -0
  921. data/lib/phusion_passenger/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +17 -0
  922. data/lib/phusion_passenger/templates/standalone/run_installer_as_root.txt.erb +8 -0
  923. data/lib/phusion_passenger/templates/standalone/welcome.txt.erb +8 -0
  924. data/lib/phusion_passenger/templates/standalone_default_root/index.html +1 -0
  925. data/lib/phusion_passenger/templates/version_not_found.html.erb +2 -2
  926. data/lib/phusion_passenger/utils.rb +476 -125
  927. data/lib/phusion_passenger/utils/file_system_watcher.rb +186 -0
  928. data/lib/phusion_passenger/utils/hosts_file_parser.rb +130 -0
  929. data/lib/phusion_passenger/utils/tmpdir.rb +70 -0
  930. data/lib/phusion_passenger/utils/unseekable_socket.rb +196 -0
  931. data/lib/phusion_passenger/wsgi/application_spawner.rb +24 -20
  932. data/lib/phusion_passenger/wsgi/request_handler.py +1 -1
  933. data/misc/copy_boost_headers.rb +36 -9
  934. data/misc/find_owner_pipe_leaks.rb +1 -1
  935. data/misc/render_error_pages.rb +1 -1
  936. data/misc/union_station_gateway.crt +32 -0
  937. data/test/config.yml.example +24 -13
  938. data/test/cxx/ApplicationPool_PoolTest.cpp +33 -0
  939. data/test/cxx/ApplicationPool_PoolTestCases.cpp +1029 -0
  940. data/test/cxx/ApplicationPool_ServerTest.cpp +308 -0
  941. data/test/cxx/ApplicationPool_Server_PoolTest.cpp +80 -0
  942. data/test/{Base64Test.cpp → cxx/Base64Test.cpp} +4 -2
  943. data/test/{CachedFileStatTest.cpp → cxx/CachedFileStatTest.cpp} +3 -3
  944. data/test/{CxxTestMain.cpp → cxx/CxxTestMain.cpp} +6 -27
  945. data/test/cxx/EventedClientTest.cpp +386 -0
  946. data/test/{FileChangeCheckerTest.cpp → cxx/FileChangeCheckerTest.cpp} +3 -5
  947. data/test/cxx/FileDescriptorTest.cpp +69 -0
  948. data/test/{HttpStatusExtractorTest.cpp → cxx/HttpStatusExtractorTest.cpp} +1 -1
  949. data/test/cxx/IOUtilsTest.cpp +398 -0
  950. data/test/cxx/LoggingTest.cpp +914 -0
  951. data/test/cxx/MessageChannelTest.cpp +672 -0
  952. data/test/cxx/MessageReadersWritersTest.cpp +574 -0
  953. data/test/cxx/MessageServerTest.cpp +383 -0
  954. data/test/{PoolOptionsTest.cpp → cxx/PoolOptionsTest.cpp} +2 -3
  955. data/test/{ScgiRequestParserTest.cpp → cxx/ScgiRequestParserTest.cpp} +53 -1
  956. data/test/cxx/ServerInstanceDirTest.cpp +186 -0
  957. data/test/cxx/SpawnManagerTest.cpp +161 -0
  958. data/test/cxx/StaticStringTest.cpp +86 -0
  959. data/test/{SystemTimeTest.cpp → cxx/SystemTimeTest.cpp} +2 -2
  960. data/test/cxx/TestSupport.cpp +166 -0
  961. data/test/cxx/TestSupport.h +254 -0
  962. data/test/cxx/UtilsTest.cpp +521 -0
  963. data/test/cxx/VariantMapTest.cpp +179 -0
  964. data/test/integration_tests/apache2_tests.rb +198 -127
  965. data/test/integration_tests/cgi_environment_spec.rb +26 -0
  966. data/test/integration_tests/mycook_spec.rb +2 -28
  967. data/test/integration_tests/nginx_tests.rb +125 -16
  968. data/test/integration_tests/spec_helper.rb +19 -0
  969. data/test/oxt/backtrace_test.cpp +19 -59
  970. data/test/oxt/counter.hpp +55 -0
  971. data/test/oxt/dynamic_thread_group_test.cpp +131 -0
  972. data/test/oxt/oxt_test_main.cpp +2 -2
  973. data/test/oxt/spin_lock_test.cpp +59 -0
  974. data/test/oxt/syscall_interruption_test.cpp +1 -1
  975. data/test/ruby/abstract_request_handler_spec.rb +346 -25
  976. data/test/ruby/abstract_server_collection_spec.rb +4 -3
  977. data/test/ruby/abstract_server_spec.rb +37 -27
  978. data/test/ruby/admin_tools_spec.rb +362 -0
  979. data/test/ruby/analytics_logger_spec.rb +253 -0
  980. data/test/ruby/{application_spec.rb → app_process_spec.rb} +14 -14
  981. data/test/ruby/classic_rails/application_spawner_spec.rb +89 -0
  982. data/test/ruby/classic_rails/framework_spawner_spec.rb +92 -0
  983. data/test/ruby/debug_logging_spec.rb +141 -0
  984. data/test/ruby/message_channel_spec.rb +51 -25
  985. data/test/ruby/rack/application_spawner_spec.rb +99 -82
  986. data/test/ruby/shared/abstract_server_spec.rb +23 -0
  987. data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +375 -0
  988. data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +38 -0
  989. data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +19 -0
  990. data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +15 -0
  991. data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +27 -0
  992. data/test/ruby/shared/spawners/preloading_spawner_spec.rb +29 -0
  993. data/test/ruby/shared/spawners/reload_all_spec.rb +36 -0
  994. data/test/ruby/shared/spawners/reload_single_spec.rb +52 -0
  995. data/test/ruby/shared/spawners/spawn_server_spec.rb +28 -0
  996. data/test/ruby/shared/spawners/spawner_spec.rb +273 -0
  997. data/test/ruby/shared/utils/pseudo_io_spec.rb +60 -0
  998. data/test/ruby/spawn_manager_spec.rb +104 -175
  999. data/test/ruby/spec_helper.rb +104 -0
  1000. data/test/ruby/utils/file_system_watcher_spec.rb +221 -0
  1001. data/test/ruby/utils/hosts_file_parser.rb +258 -0
  1002. data/test/ruby/utils/unseekable_socket_spec.rb +66 -0
  1003. data/test/ruby/utils_spec.rb +410 -59
  1004. data/test/ruby/wsgi/application_spawner_spec.rb +16 -20
  1005. data/test/stub/apache2/httpd.conf.erb +11 -6
  1006. data/test/stub/message_channel.rb +3 -1
  1007. data/test/stub/message_channel_2.rb +3 -1
  1008. data/test/stub/message_channel_3.rb +5 -3
  1009. data/test/stub/nginx/nginx.conf.erb +3 -2
  1010. data/test/stub/rails_apps/1.2/empty/Rakefile +10 -0
  1011. data/test/stub/rails_apps/1.2/empty/app/controllers/application.rb +7 -0
  1012. data/test/stub/rails_apps/{foobar → 1.2/empty}/app/helpers/application_helper.rb +0 -0
  1013. data/test/stub/rails_apps/{mycook → 1.2/empty}/config/boot.rb +3 -3
  1014. data/test/stub/rails_apps/1.2/empty/config/database.yml +31 -0
  1015. data/test/stub/rails_apps/1.2/empty/config/environment.rb +66 -0
  1016. data/test/stub/rails_apps/1.2/empty/config/environments/development.rb +21 -0
  1017. data/test/stub/rails_apps/{foobar → 1.2/empty}/config/environments/production.rb +0 -0
  1018. data/test/stub/rails_apps/1.2/empty/config/environments/staging.rb +18 -0
  1019. data/test/stub/rails_apps/1.2/empty/config/environments/test.rb +19 -0
  1020. data/test/stub/rails_apps/1.2/empty/config/routes.rb +23 -0
  1021. data/test/stub/rails_apps/1.2/empty/doc/README_FOR_APP +2 -0
  1022. data/test/stub/rails_apps/{mycook → 1.2/empty}/public/404.html +0 -0
  1023. data/test/stub/rails_apps/1.2/empty/public/500.html +30 -0
  1024. data/test/stub/rails_apps/1.2/empty/public/dispatch.cgi +10 -0
  1025. data/test/stub/rails_apps/1.2/empty/public/dispatch.fcgi +24 -0
  1026. data/test/stub/rails_apps/1.2/empty/public/dispatch.rb +10 -0
  1027. data/test/stub/rails_apps/{mycook → 1.2/empty}/public/favicon.ico +0 -0
  1028. data/test/stub/rails_apps/{mycook → 1.2/empty}/public/images/rails.png +0 -0
  1029. data/test/stub/rails_apps/1.2/empty/public/robots.txt +1 -0
  1030. data/test/stub/rails_apps/1.2/empty/script/about +3 -0
  1031. data/test/stub/rails_apps/1.2/empty/script/breakpointer +3 -0
  1032. data/test/stub/rails_apps/1.2/empty/script/console +3 -0
  1033. data/test/stub/rails_apps/1.2/empty/script/destroy +3 -0
  1034. data/test/stub/rails_apps/1.2/empty/script/generate +3 -0
  1035. data/test/stub/rails_apps/1.2/empty/script/performance/benchmarker +3 -0
  1036. data/test/stub/rails_apps/1.2/empty/script/performance/profiler +3 -0
  1037. data/test/stub/rails_apps/1.2/empty/script/plugin +3 -0
  1038. data/test/stub/rails_apps/1.2/empty/script/process/inspector +3 -0
  1039. data/test/stub/rails_apps/1.2/empty/script/process/reaper +3 -0
  1040. data/test/stub/rails_apps/1.2/empty/script/process/spawner +3 -0
  1041. data/test/stub/rails_apps/1.2/empty/script/runner +3 -0
  1042. data/test/stub/rails_apps/1.2/empty/script/server +3 -0
  1043. data/test/stub/rails_apps/1.2/empty/test/test_helper.rb +28 -0
  1044. data/test/stub/rails_apps/2.0/empty/Rakefile +10 -0
  1045. data/test/stub/rails_apps/2.0/empty/app/controllers/application.rb +10 -0
  1046. data/test/stub/rails_apps/{mycook → 2.0/empty}/app/helpers/application_helper.rb +0 -0
  1047. data/test/stub/rails_apps/{foobar → 2.0/empty}/config/boot.rb +3 -3
  1048. data/test/stub/rails_apps/2.0/empty/config/database.yml +31 -0
  1049. data/test/stub/rails_apps/2.0/empty/config/environment.rb +59 -0
  1050. data/test/stub/rails_apps/{mycook → 2.0/empty}/config/environments/development.rb +1 -1
  1051. data/test/stub/rails_apps/2.0/empty/config/environments/production.rb +18 -0
  1052. data/test/stub/rails_apps/2.0/empty/config/environments/staging.rb +18 -0
  1053. data/test/stub/rails_apps/2.0/empty/config/environments/test.rb +22 -0
  1054. data/test/stub/rails_apps/{foobar → 2.0/empty}/config/initializers/inflections.rb +0 -0
  1055. data/test/stub/rails_apps/{foobar → 2.0/empty}/config/initializers/mime_types.rb +0 -0
  1056. data/test/stub/rails_apps/{foobar → 2.0/empty}/config/routes.rb +0 -0
  1057. data/test/stub/rails_apps/2.0/empty/doc/README_FOR_APP +2 -0
  1058. data/test/stub/rails_apps/2.0/empty/public/404.html +30 -0
  1059. data/test/stub/rails_apps/{mycook → 2.0/empty}/public/422.html +0 -0
  1060. data/test/stub/rails_apps/{mycook → 2.0/empty}/public/500.html +0 -0
  1061. data/test/stub/rails_apps/2.0/empty/public/dispatch.cgi +10 -0
  1062. data/test/stub/rails_apps/2.0/empty/public/dispatch.fcgi +24 -0
  1063. data/test/stub/rails_apps/2.0/empty/public/dispatch.rb +10 -0
  1064. data/test/stub/rails_apps/2.0/empty/public/favicon.ico +0 -0
  1065. data/test/stub/rails_apps/2.0/empty/public/images/rails.png +0 -0
  1066. data/test/stub/rails_apps/{mycook → 2.0/empty}/public/robots.txt +0 -0
  1067. data/test/stub/rails_apps/2.0/empty/script/about +3 -0
  1068. data/test/stub/rails_apps/2.0/empty/script/console +3 -0
  1069. data/test/stub/rails_apps/2.0/empty/script/destroy +3 -0
  1070. data/test/stub/rails_apps/2.0/empty/script/generate +3 -0
  1071. data/test/stub/rails_apps/2.0/empty/script/performance/benchmarker +3 -0
  1072. data/test/stub/rails_apps/2.0/empty/script/performance/profiler +3 -0
  1073. data/test/stub/rails_apps/2.0/empty/script/performance/request +3 -0
  1074. data/test/stub/rails_apps/2.0/empty/script/plugin +3 -0
  1075. data/test/stub/rails_apps/2.0/empty/script/process/inspector +3 -0
  1076. data/test/stub/rails_apps/2.0/empty/script/process/reaper +3 -0
  1077. data/test/stub/rails_apps/2.0/empty/script/process/spawner +3 -0
  1078. data/test/stub/rails_apps/2.0/empty/script/runner +3 -0
  1079. data/test/stub/rails_apps/2.0/empty/script/server +3 -0
  1080. data/test/stub/rails_apps/2.0/empty/test/test_helper.rb +38 -0
  1081. data/test/stub/rails_apps/2.2/empty/Rakefile +10 -0
  1082. data/test/stub/rails_apps/2.2/empty/app/controllers/application.rb +15 -0
  1083. data/test/stub/rails_apps/2.2/empty/app/helpers/application_helper.rb +3 -0
  1084. data/test/stub/rails_apps/2.2/empty/config/boot.rb +109 -0
  1085. data/test/stub/rails_apps/2.2/empty/config/database.yml +31 -0
  1086. data/test/stub/rails_apps/2.2/empty/config/environment.rb +75 -0
  1087. data/test/stub/rails_apps/{foobar → 2.2/empty}/config/environments/development.rb +0 -0
  1088. data/test/stub/rails_apps/2.2/empty/config/environments/production.rb +24 -0
  1089. data/test/stub/rails_apps/2.2/empty/config/environments/staging.rb +24 -0
  1090. data/test/stub/rails_apps/2.2/empty/config/environments/test.rb +22 -0
  1091. data/test/stub/rails_apps/2.2/empty/config/initializers/inflections.rb +10 -0
  1092. data/test/stub/rails_apps/{mycook → 2.2/empty}/config/initializers/mime_types.rb +0 -0
  1093. data/test/stub/rails_apps/2.2/empty/config/initializers/new_rails_defaults.rb +17 -0
  1094. data/test/stub/rails_apps/2.2/empty/config/locales/en.yml +5 -0
  1095. data/test/stub/rails_apps/2.2/empty/config/routes.rb +43 -0
  1096. data/test/stub/rails_apps/2.2/empty/doc/README_FOR_APP +5 -0
  1097. data/test/stub/rails_apps/2.2/empty/public/404.html +30 -0
  1098. data/test/stub/rails_apps/2.2/empty/public/422.html +30 -0
  1099. data/test/stub/rails_apps/2.2/empty/public/500.html +33 -0
  1100. data/test/stub/rails_apps/2.2/empty/public/dispatch.cgi +10 -0
  1101. data/test/stub/rails_apps/2.2/empty/public/dispatch.fcgi +24 -0
  1102. data/test/stub/rails_apps/2.2/empty/public/dispatch.rb +10 -0
  1103. data/test/stub/rails_apps/2.2/empty/public/favicon.ico +0 -0
  1104. data/test/stub/rails_apps/2.2/empty/public/images/rails.png +0 -0
  1105. data/test/stub/rails_apps/2.2/empty/public/robots.txt +5 -0
  1106. data/test/stub/rails_apps/2.2/empty/script/about +4 -0
  1107. data/test/stub/rails_apps/2.2/empty/script/console +3 -0
  1108. data/test/stub/rails_apps/2.2/empty/script/dbconsole +3 -0
  1109. data/test/stub/rails_apps/2.2/empty/script/destroy +3 -0
  1110. data/test/stub/rails_apps/2.2/empty/script/generate +3 -0
  1111. data/test/stub/rails_apps/2.2/empty/script/performance/benchmarker +3 -0
  1112. data/test/stub/rails_apps/2.2/empty/script/performance/profiler +3 -0
  1113. data/test/stub/rails_apps/2.2/empty/script/performance/request +3 -0
  1114. data/test/stub/rails_apps/2.2/empty/script/plugin +3 -0
  1115. data/test/stub/rails_apps/2.2/empty/script/process/inspector +3 -0
  1116. data/test/stub/rails_apps/2.2/empty/script/process/reaper +3 -0
  1117. data/test/stub/rails_apps/2.2/empty/script/process/spawner +3 -0
  1118. data/test/stub/rails_apps/2.2/empty/script/runner +3 -0
  1119. data/test/stub/rails_apps/2.2/empty/script/server +3 -0
  1120. data/test/stub/rails_apps/2.2/empty/test/performance/browsing_test.rb +9 -0
  1121. data/test/stub/rails_apps/2.2/empty/test/test_helper.rb +38 -0
  1122. data/test/stub/rails_apps/2.3/empty/Rakefile +10 -0
  1123. data/test/stub/rails_apps/2.3/empty/app/controllers/application_controller.rb +10 -0
  1124. data/test/stub/rails_apps/2.3/empty/app/helpers/application_helper.rb +3 -0
  1125. data/test/stub/rails_apps/2.3/empty/config/boot.rb +110 -0
  1126. data/test/stub/rails_apps/2.3/empty/config/database.yml +31 -0
  1127. data/test/stub/rails_apps/2.3/empty/config/environment.rb +41 -0
  1128. data/test/stub/rails_apps/2.3/empty/config/environments/development.rb +17 -0
  1129. data/test/stub/rails_apps/2.3/empty/config/environments/production.rb +28 -0
  1130. data/test/stub/rails_apps/2.3/empty/config/environments/staging.rb +28 -0
  1131. data/test/stub/rails_apps/2.3/empty/config/environments/test.rb +28 -0
  1132. data/test/stub/rails_apps/2.3/empty/config/initializers/backtrace_silencers.rb +7 -0
  1133. data/test/stub/rails_apps/2.3/empty/config/initializers/inflections.rb +10 -0
  1134. data/test/stub/rails_apps/2.3/empty/config/initializers/mime_types.rb +5 -0
  1135. data/test/stub/rails_apps/2.3/empty/config/initializers/new_rails_defaults.rb +21 -0
  1136. data/test/stub/rails_apps/2.3/empty/config/initializers/session_store.rb +15 -0
  1137. data/test/stub/rails_apps/2.3/empty/config/locales/en.yml +5 -0
  1138. data/test/stub/rails_apps/2.3/empty/config/routes.rb +43 -0
  1139. data/test/stub/rails_apps/2.3/empty/db/seeds.rb +7 -0
  1140. data/test/stub/rails_apps/2.3/empty/doc/README_FOR_APP +2 -0
  1141. data/test/stub/rails_apps/2.3/empty/public/404.html +30 -0
  1142. data/test/stub/rails_apps/2.3/empty/public/422.html +30 -0
  1143. data/test/stub/rails_apps/2.3/empty/public/500.html +30 -0
  1144. data/test/stub/rails_apps/2.3/empty/public/favicon.ico +0 -0
  1145. data/test/stub/rails_apps/2.3/empty/public/images/rails.png +0 -0
  1146. data/test/stub/rails_apps/2.3/empty/public/robots.txt +5 -0
  1147. data/test/stub/rails_apps/2.3/empty/script/about +4 -0
  1148. data/test/stub/rails_apps/2.3/empty/script/console +3 -0
  1149. data/test/stub/rails_apps/2.3/empty/script/dbconsole +3 -0
  1150. data/test/stub/rails_apps/2.3/empty/script/destroy +3 -0
  1151. data/test/stub/rails_apps/2.3/empty/script/generate +3 -0
  1152. data/test/stub/rails_apps/2.3/empty/script/performance/benchmarker +3 -0
  1153. data/test/stub/rails_apps/2.3/empty/script/performance/profiler +3 -0
  1154. data/test/stub/rails_apps/2.3/empty/script/plugin +3 -0
  1155. data/test/stub/rails_apps/2.3/empty/script/runner +3 -0
  1156. data/test/stub/rails_apps/2.3/empty/script/server +3 -0
  1157. data/test/stub/rails_apps/2.3/empty/test/performance/browsing_test.rb +9 -0
  1158. data/test/stub/rails_apps/2.3/empty/test/test_helper.rb +38 -0
  1159. data/test/stub/rails_apps/2.3/foobar/Rakefile +10 -0
  1160. data/test/stub/rails_apps/{foobar/app/controllers/application.rb → 2.3/foobar/app/controllers/application_controller.rb} +0 -0
  1161. data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/bar_controller_1.rb +0 -0
  1162. data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/bar_controller_2.rb +0 -0
  1163. data/test/stub/rails_apps/{foobar → 2.3/foobar}/app/controllers/foo_controller.rb +0 -0
  1164. data/test/stub/rails_apps/2.3/foobar/app/helpers/application_helper.rb +3 -0
  1165. data/test/stub/rails_apps/2.3/foobar/config/boot.rb +110 -0
  1166. data/test/stub/rails_apps/{foobar → 2.3/foobar}/config/database.yml +0 -0
  1167. data/test/stub/rails_apps/{foobar → 2.3/foobar}/config/environment.rb +1 -1
  1168. data/test/stub/rails_apps/2.3/foobar/config/environments/development.rb +17 -0
  1169. data/test/stub/rails_apps/2.3/foobar/config/environments/production.rb +18 -0
  1170. data/test/stub/rails_apps/2.3/foobar/config/environments/staging.rb +18 -0
  1171. data/test/stub/rails_apps/{mycook → 2.3/foobar}/config/initializers/inflections.rb +0 -0
  1172. data/test/stub/rails_apps/2.3/foobar/config/initializers/mime_types.rb +5 -0
  1173. data/test/stub/rails_apps/2.3/foobar/config/routes.rb +35 -0
  1174. data/test/stub/rails_apps/2.3/foobar/script/about +3 -0
  1175. data/test/stub/rails_apps/2.3/foobar/script/console +3 -0
  1176. data/test/stub/rails_apps/2.3/foobar/script/dbconsole +3 -0
  1177. data/test/stub/rails_apps/2.3/foobar/script/destroy +3 -0
  1178. data/test/stub/rails_apps/2.3/foobar/script/generate +3 -0
  1179. data/test/stub/rails_apps/2.3/foobar/script/performance/benchmarker +3 -0
  1180. data/test/stub/rails_apps/2.3/foobar/script/performance/profiler +3 -0
  1181. data/test/stub/rails_apps/2.3/foobar/script/performance/request +3 -0
  1182. data/test/stub/rails_apps/2.3/foobar/script/plugin +3 -0
  1183. data/test/stub/rails_apps/2.3/foobar/script/process/inspector +3 -0
  1184. data/test/stub/rails_apps/2.3/foobar/script/process/reaper +3 -0
  1185. data/test/stub/rails_apps/2.3/foobar/script/process/spawner +3 -0
  1186. data/test/stub/rails_apps/2.3/foobar/script/runner +3 -0
  1187. data/test/stub/rails_apps/2.3/foobar/script/server +3 -0
  1188. data/test/stub/rails_apps/2.3/mycook/Rakefile +10 -0
  1189. data/test/stub/rails_apps/{mycook/app/controllers/application.rb → 2.3/mycook/app/controllers/application_controller.rb} +0 -0
  1190. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/recipes_controller.rb +0 -0
  1191. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/uploads_controller.rb +0 -0
  1192. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/controllers/welcome_controller.rb +0 -0
  1193. data/test/stub/rails_apps/2.3/mycook/app/helpers/application_helper.rb +3 -0
  1194. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/layouts/default.rhtml +0 -0
  1195. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/create.rhtml +0 -0
  1196. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/index.rhtml +0 -0
  1197. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/recipes/new.rhtml +0 -0
  1198. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/uploads/index.rhtml +0 -0
  1199. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/uploads/new.html.erb +0 -0
  1200. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/welcome/cached.rhtml +0 -0
  1201. data/test/stub/rails_apps/{mycook → 2.3/mycook}/app/views/welcome/index.rhtml +0 -0
  1202. data/test/stub/rails_apps/2.3/mycook/config/boot.rb +110 -0
  1203. data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/database.yml +0 -0
  1204. data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/environment.rb +1 -1
  1205. data/test/stub/rails_apps/2.3/mycook/config/environments/development.rb +18 -0
  1206. data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/environments/production.rb +0 -0
  1207. data/test/stub/rails_apps/2.3/mycook/config/initializers/inflections.rb +10 -0
  1208. data/test/stub/rails_apps/2.3/mycook/config/initializers/mime_types.rb +5 -0
  1209. data/test/stub/rails_apps/{mycook → 2.3/mycook}/config/routes.rb +0 -0
  1210. data/test/stub/rails_apps/{mycook → 2.3/mycook}/log/useless.txt +0 -0
  1211. data/test/stub/rails_apps/2.3/mycook/public/404.html +30 -0
  1212. data/test/stub/rails_apps/2.3/mycook/public/422.html +30 -0
  1213. data/test/stub/rails_apps/2.3/mycook/public/500.html +30 -0
  1214. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.cgi +0 -0
  1215. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.fcgi +0 -0
  1216. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/dispatch.rb +1 -1
  1217. data/test/stub/rails_apps/2.3/mycook/public/favicon.ico +0 -0
  1218. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/angrywizard.gif +0 -0
  1219. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/cookbook.gif +0 -0
  1220. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/images/header.png +0 -0
  1221. data/test/stub/rails_apps/2.3/mycook/public/images/rails.png +0 -0
  1222. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/application.js +0 -0
  1223. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/controls.js +73 -73
  1224. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/dragdrop.js +166 -165
  1225. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/effects.js +174 -166
  1226. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/javascripts/prototype.js +362 -267
  1227. data/test/stub/rails_apps/2.3/mycook/public/robots.txt +5 -0
  1228. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/uploads.html +0 -0
  1229. data/test/stub/rails_apps/{mycook → 2.3/mycook}/public/welcome/cached.html +0 -0
  1230. data/test/stub/rails_apps/2.3/mycook/script/about +3 -0
  1231. data/test/stub/rails_apps/2.3/mycook/script/console +3 -0
  1232. data/test/stub/rails_apps/2.3/mycook/script/dbconsole +3 -0
  1233. data/test/stub/rails_apps/2.3/mycook/script/destroy +3 -0
  1234. data/test/stub/rails_apps/2.3/mycook/script/generate +3 -0
  1235. data/test/stub/rails_apps/2.3/mycook/script/performance/benchmarker +3 -0
  1236. data/test/stub/rails_apps/2.3/mycook/script/performance/profiler +3 -0
  1237. data/test/stub/rails_apps/2.3/mycook/script/performance/request +3 -0
  1238. data/test/stub/rails_apps/2.3/mycook/script/plugin +3 -0
  1239. data/test/stub/rails_apps/2.3/mycook/script/process/inspector +3 -0
  1240. data/test/stub/rails_apps/2.3/mycook/script/process/reaper +3 -0
  1241. data/test/stub/rails_apps/2.3/mycook/script/process/spawner +3 -0
  1242. data/test/stub/rails_apps/2.3/mycook/script/runner +3 -0
  1243. data/test/stub/rails_apps/2.3/mycook/script/server +3 -0
  1244. data/test/stub/rails_apps/{mycook → 2.3/mycook}/sites/some.site/public/uploads.html +0 -0
  1245. data/test/stub/rails_apps/{mycook → 2.3/mycook}/sites/some.site/public/welcome/cached.html +0 -0
  1246. data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/cache/useless.txt +0 -0
  1247. data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/pids/useless.txt +0 -0
  1248. data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/sessions/useless.txt +0 -0
  1249. data/test/stub/rails_apps/{mycook → 2.3/mycook}/tmp/sockets/useless.txt +0 -0
  1250. data/test/stub/rails_apps/3.0/empty/Gemfile +22 -0
  1251. data/test/stub/rails_apps/3.0/empty/Rakefile +10 -0
  1252. data/test/stub/rails_apps/3.0/empty/app/controllers/application_controller.rb +4 -0
  1253. data/test/stub/rails_apps/3.0/empty/app/helpers/application_helper.rb +2 -0
  1254. data/test/stub/rails_apps/3.0/empty/app/views/layouts/application.html.erb +14 -0
  1255. data/test/stub/rails_apps/3.0/empty/config.ru +4 -0
  1256. data/test/stub/rails_apps/3.0/empty/config/application.rb +48 -0
  1257. data/test/stub/rails_apps/3.0/empty/config/boot.rb +13 -0
  1258. data/test/stub/rails_apps/3.0/empty/config/database.yml +22 -0
  1259. data/test/stub/rails_apps/3.0/empty/config/environment.rb +5 -0
  1260. data/test/stub/rails_apps/3.0/empty/config/environments/development.rb +19 -0
  1261. data/test/stub/rails_apps/3.0/empty/config/environments/production.rb +48 -0
  1262. data/test/stub/rails_apps/3.0/empty/config/environments/test.rb +32 -0
  1263. data/test/stub/rails_apps/3.0/empty/config/initializers/backtrace_silencers.rb +7 -0
  1264. data/test/stub/rails_apps/3.0/empty/config/initializers/inflections.rb +10 -0
  1265. data/test/stub/rails_apps/3.0/empty/config/initializers/mime_types.rb +5 -0
  1266. data/test/stub/rails_apps/3.0/empty/config/initializers/passenger.rb +1 -0
  1267. data/test/stub/rails_apps/3.0/empty/config/initializers/secret_token.rb +7 -0
  1268. data/test/stub/rails_apps/3.0/empty/config/initializers/session_store.rb +8 -0
  1269. data/test/stub/rails_apps/3.0/empty/config/locales/en.yml +5 -0
  1270. data/test/stub/rails_apps/3.0/empty/config/routes.rb +58 -0
  1271. data/test/stub/rails_apps/3.0/empty/db/seeds.rb +7 -0
  1272. data/test/stub/rails_apps/3.0/empty/doc/README_FOR_APP +2 -0
  1273. data/test/stub/rails_apps/3.0/empty/log/development.log +3 -0
  1274. data/test/stub/rails_apps/3.0/empty/public/404.html +26 -0
  1275. data/test/stub/rails_apps/3.0/empty/public/422.html +26 -0
  1276. data/test/stub/rails_apps/3.0/empty/public/500.html +26 -0
  1277. data/test/stub/rails_apps/3.0/empty/public/favicon.ico +0 -0
  1278. data/test/stub/rails_apps/3.0/empty/public/index.html +279 -0
  1279. data/test/stub/rails_apps/3.0/empty/public/robots.txt +5 -0
  1280. data/test/stub/rails_apps/3.0/empty/script/rails +9 -0
  1281. data/test/stub/rails_apps/3.0/empty/test/performance/browsing_test.rb +9 -0
  1282. data/test/stub/rails_apps/3.0/empty/test/test_helper.rb +13 -0
  1283. data/test/stub/spawn_server.rb +4 -2
  1284. data/test/stub/vendor_rails/minimal/actionpack/lib/action_controller.rb +3 -0
  1285. data/test/stub/vendor_rails/minimal/railties/lib/initializer.rb +7 -2
  1286. data/test/support/apache2_controller.rb +10 -2
  1287. data/test/support/nginx_controller.rb +3 -2
  1288. data/test/support/test_helper.rb +282 -46
  1289. data/test/{support → tut}/tut.h +6 -0
  1290. data/test/{support → tut}/tut_reporter.h +0 -0
  1291. metadata +824 -266
  1292. data/benchmark/ApplicationPool.cpp +0 -52
  1293. data/benchmark/accept_vs_socketpair_vs_named_pipes.rb +0 -126
  1294. data/benchmark/dispatcher.rb +0 -42
  1295. data/benchmark/overhead_of_password_checking.rb +0 -81
  1296. data/benchmark/socket_connections_vs_persistent_pipe.rb +0 -99
  1297. data/benchmark/unix_sockets_vs_pipes.rb +0 -83
  1298. data/ext/boost/LICENSE.TXT +0 -23
  1299. data/ext/boost/VERSION.TXT +0 -1
  1300. data/ext/boost/detail/sp_counted_base.hpp +0 -81
  1301. data/ext/boost/src/pthread/exceptions.cpp +0 -146
  1302. data/ext/boost/src/win32/exceptions.cpp +0 -124
  1303. data/ext/boost/src/win32/thread.cpp +0 -629
  1304. data/ext/boost/src/win32/timeconv.inl +0 -130
  1305. data/ext/boost/src/win32/tss_dll.cpp +0 -72
  1306. data/ext/boost/src/win32/tss_pe.cpp +0 -269
  1307. data/ext/boost/thread/pthread/thread.hpp +0 -339
  1308. data/ext/boost/thread/pthread/tss.hpp +0 -103
  1309. data/ext/common/Application.h +0 -511
  1310. data/ext/common/ApplicationPoolServer.h +0 -794
  1311. data/ext/common/ApplicationPoolServerExecutable.cpp +0 -743
  1312. data/ext/common/ApplicationPoolStatusReporter.h +0 -336
  1313. data/ext/common/DummySpawnManager.h +0 -108
  1314. data/ext/common/StandardApplicationPool.h +0 -821
  1315. data/ext/common/SystemTime.h +0 -88
  1316. data/lib/phusion_passenger/admin_tools/control_process.rb +0 -150
  1317. data/lib/phusion_passenger/railz/application_spawner.rb +0 -463
  1318. data/lib/phusion_passenger/templates/invalid_app_root.html.erb +0 -9
  1319. data/test/ApplicationPoolServerTest.cpp +0 -114
  1320. data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +0 -33
  1321. data/test/ApplicationPoolTest.cpp +0 -599
  1322. data/test/MessageChannelTest.cpp +0 -320
  1323. data/test/SpawnManagerTest.cpp +0 -64
  1324. data/test/StandardApplicationPoolTest.cpp +0 -27
  1325. data/test/StaticStringTest.cpp +0 -51
  1326. data/test/UtilsTest.cpp +0 -257
  1327. data/test/ruby/rails/application_spawner_spec.rb +0 -159
  1328. data/test/ruby/rails/framework_spawner_spec.rb +0 -133
  1329. data/test/ruby/rails/minimal_spawner_spec.rb +0 -93
  1330. data/test/ruby/rails/spawner_error_handling_spec.rb +0 -107
  1331. data/test/ruby/rails/spawner_privilege_lowering_spec.rb +0 -97
  1332. data/test/ruby/spawn_server_spec.rb +0 -26
  1333. data/test/stub/MessageServer.dSYM/Contents/Info.plist +0 -25
  1334. data/test/stub/MessageServer.dSYM/Contents/Resources/DWARF/MessageServer +0 -0
  1335. data/test/support/Support.cpp +0 -84
  1336. data/test/support/Support.h +0 -118
  1337. data/test/support/config.rb +0 -38
  1338. data/test/support/run_rspec_tests.rb +0 -10
@@ -0,0 +1,63 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2010 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_CHANGE_NOTIFIER_H_
26
+ #define _PASSENGER_CHANGE_NOTIFIER_H_
27
+
28
+ #include <boost/function.hpp>
29
+ #include <boost/shared_ptr.hpp>
30
+ #include <string>
31
+ #include <ev++.h>
32
+ #include "DataStoreId.h"
33
+ #include "../EventedClient.h"
34
+ #include "../FileDescriptor.h"
35
+ #include "../StaticString.h"
36
+
37
+ namespace Passenger {
38
+
39
+ using namespace std;
40
+ using namespace boost;
41
+
42
+
43
+ class ChangeNotifier {
44
+ public:
45
+ typedef function<string (const StaticString &groupName, const StaticString &nodeName,
46
+ const StaticString &category)> GetLastPosFunction;
47
+
48
+ GetLastPosFunction getLastPos;
49
+
50
+ ChangeNotifier(struct ev_loop *_loop) { }
51
+ virtual ~ChangeNotifier() { }
52
+
53
+ virtual void addClient(const FileDescriptor &fd) { }
54
+
55
+ virtual void changed(const DataStoreId &dataStoreId) { }
56
+ };
57
+
58
+ typedef shared_ptr<ChangeNotifier> ChangeNotifierPtr;
59
+
60
+
61
+ } // namespace Passenger
62
+
63
+ #endif /* _PASSENGER_CHANGE_NOTIFIER_H_ */
@@ -0,0 +1,177 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2010 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_DATA_STORE_ID_H_
26
+ #define _PASSENGER_DATA_STORE_ID_H_
27
+
28
+ #include <cstring>
29
+ #include <climits>
30
+ #include <cassert>
31
+ #include "StaticString.h"
32
+
33
+ namespace Passenger {
34
+
35
+
36
+ /**
37
+ * Efficient representation for a (groupName, nodeName, category) tuple.
38
+ */
39
+ class DataStoreId {
40
+ private:
41
+ char *id;
42
+ unsigned short groupNameSize;
43
+ unsigned short nodeNameSize;
44
+ unsigned short categorySize;
45
+
46
+ size_t totalSize() const {
47
+ return groupNameSize + nodeNameSize + categorySize + 3;
48
+ }
49
+
50
+ StaticString toStaticString() const {
51
+ if (id == NULL) {
52
+ return StaticString();
53
+ } else {
54
+ return StaticString(id, totalSize());
55
+ }
56
+ }
57
+
58
+ public:
59
+ DataStoreId(const StaticString &groupName, const StaticString &nodeName,
60
+ const StaticString &category)
61
+ {
62
+ assert(groupName.size() <= USHRT_MAX);
63
+ assert(nodeName.size() <= USHRT_MAX);
64
+ assert(category.size() <= USHRT_MAX);
65
+
66
+ char *end;
67
+
68
+ id = new char[groupName.size() + nodeName.size() +
69
+ category.size() + 3];
70
+ end = id;
71
+
72
+ memcpy(end, groupName.c_str(), groupName.size());
73
+ groupNameSize = groupName.size();
74
+ end += groupName.size();
75
+ *end = '\0';
76
+ end++;
77
+
78
+ memcpy(end, nodeName.c_str(), nodeName.size());
79
+ nodeNameSize = nodeName.size();
80
+ end += nodeName.size();
81
+ *end = '\0';
82
+ end++;
83
+
84
+ memcpy(end, category.c_str(), category.size());
85
+ categorySize = category.size();
86
+ end += category.size();
87
+ *end = '\0';
88
+ }
89
+
90
+ DataStoreId() {
91
+ id = NULL;
92
+ }
93
+
94
+ DataStoreId(const DataStoreId &other) {
95
+ if (other.id == NULL) {
96
+ id = NULL;
97
+ } else {
98
+ id = new char[other.totalSize()];
99
+ memcpy(id, other.id, other.totalSize());
100
+ groupNameSize = other.groupNameSize;
101
+ nodeNameSize = other.nodeNameSize;
102
+ categorySize = other.categorySize;
103
+ }
104
+ }
105
+
106
+ ~DataStoreId() {
107
+ delete id;
108
+ }
109
+
110
+ DataStoreId &operator=(const DataStoreId &other) {
111
+ if (other.id == NULL) {
112
+ delete id;
113
+ id = NULL;
114
+ return *this;
115
+ } else {
116
+ if (totalSize() != other.totalSize()) {
117
+ delete id;
118
+ id = NULL;
119
+ }
120
+ if (id == NULL) {
121
+ id = new char[other.totalSize()];
122
+ }
123
+ memcpy(id, other.id, other.totalSize());
124
+ groupNameSize = other.groupNameSize;
125
+ nodeNameSize = other.nodeNameSize;
126
+ categorySize = other.categorySize;
127
+ return *this;
128
+ }
129
+ }
130
+
131
+ bool operator<(const DataStoreId &other) const {
132
+ return toStaticString() < other.toStaticString();
133
+ }
134
+
135
+ bool operator==(const DataStoreId &other) const {
136
+ if (id == NULL) {
137
+ return other.id == NULL;
138
+ } else {
139
+ if (other.id == NULL) {
140
+ return false;
141
+ } else {
142
+ return toStaticString() == other.toStaticString();
143
+ }
144
+ }
145
+ }
146
+
147
+ StaticString getGroupName() const {
148
+ if (id != NULL) {
149
+ return StaticString(id, groupNameSize);
150
+ } else {
151
+ return StaticString();
152
+ }
153
+ }
154
+
155
+ StaticString getNodeName() const {
156
+ if (id != NULL) {
157
+ return StaticString(id + groupNameSize + 1,
158
+ nodeNameSize);
159
+ } else {
160
+ return StaticString();
161
+ }
162
+ }
163
+
164
+ StaticString getCategory() const {
165
+ if (id != NULL) {
166
+ return StaticString(id + groupNameSize + 1 + nodeNameSize + 1,
167
+ categorySize);
168
+ } else {
169
+ return StaticString();
170
+ }
171
+ }
172
+ };
173
+
174
+
175
+ } // namespace Passenger
176
+
177
+ #endif /* _PASSENGER_DATA_STORE_ID_H_ */
@@ -0,0 +1,1343 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2010 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ */
25
+ #ifndef _PASSENGER_LOGGING_SERVER_H_
26
+ #define _PASSENGER_LOGGING_SERVER_H_
27
+
28
+ #include <oxt/system_calls.hpp>
29
+ #include <oxt/macros.hpp>
30
+ #include <boost/shared_ptr.hpp>
31
+ #include <string>
32
+ #include <ostream>
33
+ #include <sstream>
34
+ #include <map>
35
+ #include <ev++.h>
36
+
37
+ #include <sys/types.h>
38
+ #include <sys/time.h>
39
+ #include <sys/stat.h>
40
+ #include <grp.h>
41
+ #include <cstring>
42
+ #include <ctime>
43
+ #include <cassert>
44
+
45
+ #include "DataStoreId.h"
46
+ #include "RemoteSender.h"
47
+ #include "ChangeNotifier.h"
48
+ #include "../EventedMessageServer.h"
49
+ #include "../MessageReadersWriters.h"
50
+ #include "../StaticString.h"
51
+ #include "../Exceptions.h"
52
+ #include "../MessageChannel.h"
53
+ #include "../Constants.h"
54
+ #include "../Utils.h"
55
+ #include "../Utils/MD5.h"
56
+ #include "../Utils/IOUtils.h"
57
+ #include "../Utils/StrIntUtils.h"
58
+
59
+
60
+ namespace Passenger {
61
+
62
+ using namespace std;
63
+ using namespace boost;
64
+ using namespace oxt;
65
+
66
+
67
+ class LoggingServer: public EventedMessageServer {
68
+ private:
69
+ static const int MAX_LOG_SINK_CACHE_SIZE = 512;
70
+ static const int GARBAGE_COLLECTION_TIMEOUT = 1.25 * 60 * 60; // 1 hour 15 minutes
71
+
72
+ struct LogSink;
73
+ typedef shared_ptr<LogSink> LogSinkPtr;
74
+ typedef map<string, LogSinkPtr> LogSinkCache;
75
+
76
+ struct LogSink {
77
+ LoggingServer *server;
78
+
79
+ /**
80
+ * Marks how many times this LogSink is currently opened, i.e. the
81
+ * number of Transaction objects currently referencing this LogSink.
82
+ * @invariant
83
+ * (opened == 0) == (this LogSink is in LoggingServer.inactiveLogSinks)
84
+ */
85
+ int opened;
86
+
87
+ /** Last time this LogSink hit an open count of 0. */
88
+ ev_tstamp lastUsed;
89
+
90
+ /** Last time data was actually written to the underlying storage device. */
91
+ ev_tstamp lastFlushed;
92
+
93
+ /**
94
+ * This LogSink's iterator inside LoggingServer.logSinkCache.
95
+ */
96
+ LogSinkCache::iterator cacheIterator;
97
+
98
+ /**
99
+ * This LogSink's iterator inside LoggingServer.inactiveLogSinks.
100
+ * Only valid when opened == 0.
101
+ */
102
+ list<LogSinkPtr>::iterator inactiveLogSinksIterator;
103
+
104
+ LogSink(LoggingServer *_server) {
105
+ server = _server;
106
+ opened = 0;
107
+ lastUsed = ev_now(server->getLoop());
108
+ lastFlushed = 0;
109
+ }
110
+
111
+ virtual ~LogSink() {
112
+ // We really want to flush() here but can't call virtual
113
+ // functions in destructor. :(
114
+ }
115
+
116
+ virtual bool isRemote() const {
117
+ return false;
118
+ }
119
+
120
+ virtual void append(const DataStoreId &dataStoreId,
121
+ const StaticString &data) = 0;
122
+ virtual void flush() { }
123
+ virtual void dump(ostream &stream) const { }
124
+ };
125
+
126
+ struct LogFile: public LogSink {
127
+ static const unsigned int BUFFER_CAPACITY = 8 * 1024;
128
+
129
+ string filename;
130
+ FileDescriptor fd;
131
+ char buffer[BUFFER_CAPACITY];
132
+ unsigned int bufferSize;
133
+
134
+ /**
135
+ * Contains every (groupName, nodeName, category) tuple for
136
+ * which their data is currently buffered in this sink.
137
+ */
138
+ set<DataStoreId> dataStoreIds;
139
+
140
+ LogFile(LoggingServer *server, const string &filename, mode_t filePermissions)
141
+ : LogSink(server)
142
+ {
143
+ int ret;
144
+
145
+ bufferSize = 0;
146
+
147
+ this->filename = filename;
148
+ fd = syscalls::open(filename.c_str(),
149
+ O_CREAT | O_WRONLY | O_APPEND,
150
+ filePermissions);
151
+ if (fd == -1) {
152
+ int e = errno;
153
+ throw FileSystemException("Cannnot open file", e, filename);
154
+ }
155
+ do {
156
+ ret = fchmod(fd, filePermissions);
157
+ } while (ret == -1 && errno == EINTR);
158
+ }
159
+
160
+ virtual ~LogFile() {
161
+ flush();
162
+ }
163
+
164
+ void notifyChanges() {
165
+ if (server->changeNotifier != NULL) {
166
+ set<DataStoreId>::const_iterator it;
167
+ set<DataStoreId>::const_iterator end = dataStoreIds.end();
168
+
169
+ for (it = dataStoreIds.begin(); it != dataStoreIds.end(); it++) {
170
+ server->changeNotifier->changed(*it);
171
+ }
172
+ }
173
+ dataStoreIds.clear();
174
+ }
175
+
176
+ virtual void append(const DataStoreId &dataStoreId, const StaticString &data) {
177
+ if (server->changeNotifier != NULL) {
178
+ dataStoreIds.insert(dataStoreId);
179
+ }
180
+ if (bufferSize + data.size() > BUFFER_CAPACITY) {
181
+ StaticString data2[2];
182
+ data2[0] = StaticString(buffer, bufferSize);
183
+ data2[1] = data;
184
+
185
+ gatheredWrite(fd, data2, 2);
186
+ lastFlushed = ev_now(server->getLoop());
187
+ bufferSize = 0;
188
+ notifyChanges();
189
+ } else {
190
+ memcpy(buffer + bufferSize, data.data(), data.size());
191
+ bufferSize += data.size();
192
+ }
193
+ }
194
+
195
+ virtual void flush() {
196
+ if (bufferSize > 0) {
197
+ lastFlushed = ev_now(server->getLoop());
198
+ MessageChannel(fd).writeRaw(StaticString(buffer, bufferSize));
199
+ bufferSize = 0;
200
+ notifyChanges();
201
+ }
202
+ }
203
+
204
+ virtual void dump(ostream &stream) const {
205
+ stream << " Log file: file=" << filename << ", "
206
+ "opened=" << opened << ", "
207
+ "age=" << long(ev_now(server->getLoop()) - lastUsed) << "\n";
208
+ }
209
+ };
210
+
211
+ typedef shared_ptr<LogFile> LogFilePtr;
212
+
213
+ struct RemoteSink: public LogSink {
214
+ /* RemoteSender compresses the data with zlib before sending it
215
+ * to the server. Even including Base64 and URL encoding overhead,
216
+ * this compresses the data to about 25% of its original size.
217
+ * Therefore we set a buffer capacity of a little less than 4 times
218
+ * the TCP maximum segment size so that we can send as much
219
+ * data as possible to the server in a single TCP segment.
220
+ * With the "little less" we take into account:
221
+ * - HTTPS overhead. This can be as high as 2 KB.
222
+ * - The fact that RemoteSink.append() might try to flush the
223
+ * current buffer the current data. Empirical evidence has
224
+ * shown that the data for a request transaction is usually
225
+ * less than 5 KB.
226
+ */
227
+ static const unsigned int BUFFER_CAPACITY =
228
+ 4 * 64 * 1024 -
229
+ 16 * 1024;
230
+
231
+ string unionStationKey;
232
+ string nodeName;
233
+ string category;
234
+ char buffer[BUFFER_CAPACITY];
235
+ unsigned int bufferSize;
236
+
237
+ RemoteSink(LoggingServer *server, const string &unionStationKey,
238
+ const string &nodeName, const string &category)
239
+ : LogSink(server)
240
+ {
241
+ this->unionStationKey = unionStationKey;
242
+ this->nodeName = nodeName;
243
+ this->category = category;
244
+ this->bufferSize = 0;
245
+ }
246
+
247
+ virtual ~RemoteSink() {
248
+ flush();
249
+ }
250
+
251
+ virtual bool isRemote() const {
252
+ return true;
253
+ }
254
+
255
+ virtual void append(const DataStoreId &dataStoreId, const StaticString &data) {
256
+ if (bufferSize + data.size() > BUFFER_CAPACITY) {
257
+ StaticString data2[2];
258
+ data2[0] = StaticString(buffer, bufferSize);
259
+ data2[1] = data;
260
+
261
+ server->remoteSender.schedule(unionStationKey, nodeName,
262
+ category, data2, 2);
263
+ lastFlushed = ev_now(server->getLoop());
264
+ bufferSize = 0;
265
+ } else {
266
+ memcpy(buffer + bufferSize, data.data(), data.size());
267
+ bufferSize += data.size();
268
+ }
269
+ }
270
+
271
+ virtual void flush() {
272
+ if (bufferSize > 0) {
273
+ lastFlushed = ev_now(server->getLoop());
274
+ StaticString data(buffer, bufferSize);
275
+ server->remoteSender.schedule(unionStationKey, nodeName,
276
+ category, &data, 1);
277
+ bufferSize = 0;
278
+ }
279
+ }
280
+
281
+ virtual void dump(ostream &stream) const {
282
+ stream << " Remote sink: "
283
+ "key=" << unionStationKey << ", "
284
+ "node=" << nodeName << ", "
285
+ "category=" << category << ", "
286
+ "opened=" << opened << ", "
287
+ "age=" << long(ev_now(server->getLoop()) - lastUsed) << ", "
288
+ "bufferSize=" << bufferSize <<
289
+ "\n";
290
+ }
291
+ };
292
+
293
+ struct Transaction {
294
+ LoggingServer *server;
295
+ LogSinkPtr logSink;
296
+ string txnId;
297
+ DataStoreId dataStoreId;
298
+ unsigned int writeCount;
299
+ int refcount;
300
+ bool crashProtect, discarded;
301
+ string data;
302
+
303
+ Transaction(LoggingServer *server) {
304
+ this->server = server;
305
+ data.reserve(8 * 1024);
306
+ }
307
+
308
+ ~Transaction() {
309
+ if (logSink != NULL) {
310
+ if (!discarded) {
311
+ logSink->append(dataStoreId, data);
312
+ }
313
+ server->closeLogSink(logSink);
314
+ }
315
+ }
316
+
317
+ StaticString getGroupName() const {
318
+ return dataStoreId.getGroupName();
319
+ }
320
+
321
+ StaticString getNodeName() const {
322
+ return dataStoreId.getNodeName();
323
+ }
324
+
325
+ StaticString getCategory() const {
326
+ return dataStoreId.getCategory();
327
+ }
328
+
329
+ void discard() {
330
+ data.clear();
331
+ discarded = true;
332
+ }
333
+
334
+ void dump(ostream &stream) const {
335
+ stream << " Transaction " << txnId << ":\n";
336
+ stream << " Group : " << getGroupName() << "\n";
337
+ stream << " Node : " << getNodeName() << "\n";
338
+ stream << " Category: " << getCategory() << "\n";
339
+ stream << " Refcount: " << refcount << "\n";
340
+ }
341
+ };
342
+
343
+ typedef shared_ptr<Transaction> TransactionPtr;
344
+
345
+ enum ClientType {
346
+ UNINITIALIZED,
347
+ LOGGER,
348
+ WATCHER
349
+ };
350
+
351
+ struct Client: public EventedMessageClient {
352
+ string nodeName;
353
+ ClientType type;
354
+ char nodeId[MD5_HEX_SIZE];
355
+ /**
356
+ * Set of transaction IDs opened by this client.
357
+ * @invariant This is a subset of the transaction IDs in the 'transactions' member.
358
+ */
359
+ set<string> openTransactions;
360
+ ScalarMessage dataReader;
361
+ TransactionPtr currentTransaction;
362
+ string currentTimestamp;
363
+
364
+ Client(struct ev_loop *loop, const FileDescriptor &fd)
365
+ : EventedMessageClient(loop, fd)
366
+ {
367
+ type = UNINITIALIZED;
368
+ dataReader.setMaxSize(1024 * 128);
369
+ }
370
+ };
371
+
372
+ typedef shared_ptr<Client> ClientPtr;
373
+ typedef map<string, TransactionPtr> TransactionMap;
374
+
375
+ string dir;
376
+ gid_t gid;
377
+ string dirPermissions;
378
+ mode_t filePermissions;
379
+ RemoteSender remoteSender;
380
+ ChangeNotifierPtr changeNotifier;
381
+ ev::timer garbageCollectionTimer;
382
+ ev::timer sinkFlushingTimer;
383
+ ev::timer exitTimer;
384
+ TransactionMap transactions;
385
+ LogSinkCache logSinkCache;
386
+ /**
387
+ * @invariant
388
+ * inactiveLogSinks is sorted from oldest to youngest (by lastTime member).
389
+ * for all s in inactiveLogSinks:
390
+ * s.opened == 0
391
+ * inactiveLogSinks.size() == inactiveLogSinksCount
392
+ */
393
+ list<LogSinkPtr> inactiveLogSinks;
394
+ int inactiveLogSinksCount;
395
+ RandomGenerator randomGenerator;
396
+ bool refuseNewConnections;
397
+ bool exitRequested;
398
+ unsigned long long exitBeginTime;
399
+
400
+ void sendErrorToClient(Client *client, const string &message) {
401
+ client->writeArrayMessage("error", message.c_str(), NULL);
402
+ logError(client, message);
403
+ }
404
+
405
+ bool expectingArgumentsCount(Client *client, const vector<StaticString> &args, unsigned int size) {
406
+ if (args.size() == size) {
407
+ return true;
408
+ } else {
409
+ sendErrorToClient(client, "Invalid number of arguments");
410
+ client->disconnect();
411
+ return false;
412
+ }
413
+ }
414
+
415
+ bool expectingLoggerType(Client *client) {
416
+ if (client->type == LOGGER) {
417
+ return true;
418
+ } else {
419
+ sendErrorToClient(client, "Client not initialized as logger");
420
+ client->disconnect();
421
+ return false;
422
+ }
423
+ }
424
+
425
+ bool checkWhetherConnectionAreAcceptable(Client *client) {
426
+ if (refuseNewConnections) {
427
+ client->writeArrayMessage("server shutting down", NULL);
428
+ client->disconnect();
429
+ return false;
430
+ } else {
431
+ return true;
432
+ }
433
+ }
434
+
435
+ bool validTxnId(const StaticString &txnId) const {
436
+ // must contain timestamp
437
+ // must contain separator
438
+ // must contain random id
439
+ // must not be too large
440
+ return !txnId.empty();
441
+ }
442
+
443
+ bool validUnionStationKey(const StaticString &key) const {
444
+ // must be hexadecimal
445
+ // must not be too large
446
+ return !key.empty();
447
+ }
448
+
449
+ bool validLogContent(const StaticString &data) const {
450
+ const char *current = data.c_str();
451
+ const char *end = current + data.size();
452
+ while (current < end) {
453
+ char c = *current;
454
+ if ((c < 1 && c > 126) || c == '\n' || c == '\r') {
455
+ return false;
456
+ }
457
+ current++;
458
+ }
459
+ return true;
460
+ }
461
+
462
+ bool validTimestamp(const StaticString &timestamp) const {
463
+ // must be hexadecimal
464
+ // must not be too large
465
+ return true;
466
+ }
467
+
468
+ bool supportedCategory(const StaticString &category) const {
469
+ return category == "requests" || category == "processes" || category == "exceptions";
470
+ }
471
+
472
+ time_t extractTimestamp(const StaticString &txnId) const {
473
+ const char *timestampEnd = (const char *) memchr(txnId.c_str(), '-', txnId.size());
474
+ if (timestampEnd == NULL) {
475
+ return 0;
476
+ } else {
477
+ time_t timestamp = hexatriToULL(
478
+ StaticString(txnId.c_str(), timestampEnd - txnId.c_str())
479
+ );
480
+ return timestamp * 60;
481
+ }
482
+ }
483
+
484
+ void appendVersionAndGroupId(string &output, const StaticString &groupName) const {
485
+ md5_state_t state;
486
+ md5_byte_t digest[MD5_SIZE];
487
+ char checksum[MD5_HEX_SIZE];
488
+
489
+ output.append("/1/", 3);
490
+
491
+ md5_init(&state);
492
+ md5_append(&state, (const md5_byte_t *) groupName.data(), groupName.size());
493
+ md5_finish(&state, digest);
494
+ toHex(StaticString((const char *) digest, MD5_SIZE), checksum);
495
+ output.append(checksum, MD5_HEX_SIZE);
496
+ }
497
+
498
+ string determineFilename(const StaticString &groupName, const char *nodeId,
499
+ const StaticString &category, const StaticString &txnId = "") const
500
+ {
501
+ time_t timestamp;
502
+ struct tm tm;
503
+ char time_str[14];
504
+
505
+ if (!txnId.empty()) {
506
+ timestamp = extractTimestamp(txnId);
507
+ gmtime_r(&timestamp, &tm);
508
+ strftime(time_str, sizeof(time_str), "%Y/%m/%d/%H", &tm);
509
+ }
510
+
511
+ string filename;
512
+ filename.reserve(dir.size()
513
+ + (3 + MD5_HEX_SIZE) // version and group ID
514
+ + 1 // "/"
515
+ + MD5_HEX_SIZE // node ID
516
+ + 1 // "/"
517
+ + category.size()
518
+ + 1 // "/"
519
+ + sizeof(time_str) // including null terminator, which we use as space for "/"
520
+ + sizeof("log.txt")
521
+ );
522
+ filename.append(dir);
523
+ appendVersionAndGroupId(filename, groupName);
524
+ filename.append(1, '/');
525
+ filename.append(nodeId, MD5_HEX_SIZE);
526
+ filename.append(1, '/');
527
+ filename.append(category.c_str(), category.size());
528
+ if (!txnId.empty()) {
529
+ filename.append(1, '/');
530
+ filename.append(time_str);
531
+ filename.append("/log.txt");
532
+ }
533
+ return filename;
534
+ }
535
+
536
+ void setupGroupAndNodeDir(const StaticString &groupName, const StaticString &nodeName,
537
+ const char *nodeId)
538
+ {
539
+ string filename, groupDir, nodeDir;
540
+
541
+ filename.append(dir);
542
+ appendVersionAndGroupId(filename, groupName);
543
+ groupDir = filename;
544
+
545
+ filename.append("/");
546
+ filename.append(nodeId, MD5_HEX_SIZE);
547
+ nodeDir = filename;
548
+
549
+ createFile(groupDir + "/group_name.txt", groupName,
550
+ filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
551
+ false);
552
+ if (getFileType(groupDir + "/uuid.txt") == FT_NONEXISTANT) {
553
+ createFile(groupDir + "/uuid.txt",
554
+ randomGenerator.generateAsciiString(24),
555
+ filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
556
+ false);
557
+ }
558
+
559
+ createFile(nodeDir + "/node_name.txt", nodeName,
560
+ filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
561
+ false);
562
+ if (getFileType(nodeDir + "/uuid.txt") == FT_NONEXISTANT) {
563
+ createFile(nodeDir + "/uuid.txt",
564
+ randomGenerator.generateAsciiString(24),
565
+ filePermissions, USER_NOT_GIVEN, GROUP_NOT_GIVEN,
566
+ false);
567
+ }
568
+ }
569
+
570
+ bool openLogFileWithCache(const string &filename, LogSinkPtr &theLogSink) {
571
+ string cacheKey = "file:" + filename;
572
+ LogSinkCache::iterator it = logSinkCache.find(cacheKey);
573
+ if (it == logSinkCache.end()) {
574
+ trimLogSinkCache(MAX_LOG_SINK_CACHE_SIZE - 1);
575
+ makeDirTree(extractDirName(filename), dirPermissions,
576
+ USER_NOT_GIVEN, gid);
577
+ theLogSink.reset(new LogFile(this, filename, filePermissions));
578
+ pair<LogSinkCache::iterator, bool> p =
579
+ logSinkCache.insert(make_pair(cacheKey, theLogSink));
580
+ theLogSink->cacheIterator = p.first;
581
+ theLogSink->opened = 1;
582
+ return false;
583
+ } else {
584
+ theLogSink = it->second;
585
+ theLogSink->opened++;
586
+ if (theLogSink->opened == 1) {
587
+ inactiveLogSinks.erase(theLogSink->inactiveLogSinksIterator);
588
+ inactiveLogSinksCount--;
589
+ }
590
+ return true;
591
+ }
592
+ }
593
+
594
+ void openRemoteSink(const StaticString &unionStationKey, const string &nodeName,
595
+ const string &category, LogSinkPtr &theLogSink)
596
+ {
597
+ string cacheKey = "remote:";
598
+ cacheKey.append(unionStationKey.c_str(), unionStationKey.size());
599
+ cacheKey.append(1, '\0');
600
+ cacheKey.append(nodeName);
601
+ cacheKey.append(1, '\0');
602
+ cacheKey.append(category);
603
+
604
+ LogSinkCache::iterator it = logSinkCache.find(cacheKey);
605
+ if (it == logSinkCache.end()) {
606
+ trimLogSinkCache(MAX_LOG_SINK_CACHE_SIZE - 1);
607
+ theLogSink.reset(new RemoteSink(this, unionStationKey,
608
+ nodeName, category));
609
+ pair<LogSinkCache::iterator, bool> p =
610
+ logSinkCache.insert(make_pair(cacheKey, theLogSink));
611
+ theLogSink->cacheIterator = p.first;
612
+ theLogSink->opened = 1;
613
+ } else {
614
+ theLogSink = it->second;
615
+ theLogSink->opened++;
616
+ if (theLogSink->opened == 1) {
617
+ inactiveLogSinks.erase(theLogSink->inactiveLogSinksIterator);
618
+ inactiveLogSinksCount--;
619
+ }
620
+ }
621
+ }
622
+
623
+ /**
624
+ * 'Closes' the given log sink. It's not actually deleted from memory;
625
+ * instead it's marked as inactive and cached for later use. May be
626
+ * deleted later when resources are low.
627
+ *
628
+ * No need to call this manually. Automatically called by Transaction's
629
+ * destructor.
630
+ */
631
+ void closeLogSink(const LogSinkPtr &logSink) {
632
+ logSink->opened--;
633
+ assert(logSink->opened >= 0);
634
+ logSink->lastUsed = ev_now(getLoop());
635
+ if (logSink->opened == 0) {
636
+ inactiveLogSinks.push_back(logSink);
637
+ logSink->inactiveLogSinksIterator = inactiveLogSinks.end();
638
+ logSink->inactiveLogSinksIterator--;
639
+ inactiveLogSinksCount++;
640
+ trimLogSinkCache(MAX_LOG_SINK_CACHE_SIZE);
641
+ }
642
+ }
643
+
644
+ /** Try to reduce the log sink cache size to the given size. */
645
+ void trimLogSinkCache(unsigned int size) {
646
+ while (!inactiveLogSinks.empty() && logSinkCache.size() > size) {
647
+ const LogSinkPtr logSink = inactiveLogSinks.front();
648
+ inactiveLogSinks.pop_front();
649
+ inactiveLogSinksCount--;
650
+ logSinkCache.erase(logSink->cacheIterator);
651
+ }
652
+ }
653
+
654
+ bool writeLogEntry(Client *client, const TransactionPtr &transaction,
655
+ const StaticString &timestamp, const StaticString &data)
656
+ {
657
+ if (transaction->discarded) {
658
+ return true;
659
+ }
660
+ if (OXT_UNLIKELY( !validLogContent(data) )) {
661
+ if (client != NULL) {
662
+ sendErrorToClient(client, "Log entry data contains an invalid character.");
663
+ client->disconnect();
664
+ }
665
+ return false;
666
+ }
667
+ if (OXT_UNLIKELY( !validTimestamp(timestamp) )) {
668
+ if (client != NULL) {
669
+ sendErrorToClient(client, "Log entry timestamp is invalid.");
670
+ client->disconnect();
671
+ }
672
+ return false;
673
+ }
674
+
675
+ char writeCountStr[sizeof(unsigned int) * 2 + 1];
676
+ integerToHexatri(transaction->writeCount, writeCountStr);
677
+ transaction->writeCount++;
678
+ transaction->data.reserve(transaction->data.size() +
679
+ transaction->txnId.size() +
680
+ 1 +
681
+ timestamp.size() +
682
+ 1 +
683
+ strlen(writeCountStr) +
684
+ 1 +
685
+ data.size() +
686
+ 1);
687
+ transaction->data.append(transaction->txnId);
688
+ transaction->data.append(" ");
689
+ transaction->data.append(timestamp);
690
+ transaction->data.append(" ");
691
+ transaction->data.append(writeCountStr);
692
+ transaction->data.append(" ");
693
+ transaction->data.append(data);
694
+ transaction->data.append("\n");
695
+ return true;
696
+ }
697
+
698
+ void writeDetachEntry(Client *client, const TransactionPtr &transaction) {
699
+ char timestamp[2 * sizeof(unsigned long long) + 1];
700
+ // Must use System::getUsec() here instead of ev_now() because the
701
+ // precision of the time is very important.
702
+ integerToHexatri<unsigned long long>(SystemTime::getUsec(), timestamp);
703
+ writeDetachEntry(client, transaction, timestamp);
704
+ }
705
+
706
+ void writeDetachEntry(Client *client, const TransactionPtr &transaction,
707
+ const StaticString &timestamp)
708
+ {
709
+ writeLogEntry(client, transaction, timestamp, "DETACH");
710
+ }
711
+
712
+ bool requireRights(Client *client, Account::Rights rights) {
713
+ if (client->messageServer.account->hasRights(rights)) {
714
+ return true;
715
+ } else {
716
+ P_TRACE(2, "Security error: insufficient rights to execute this command.");
717
+ client->writeArrayMessage("SecurityException",
718
+ "Insufficient rights to execute this command.",
719
+ NULL);
720
+ client->disconnect();
721
+ return false;
722
+ }
723
+ }
724
+
725
+ bool isDirectory(const string &dir, struct dirent *entry) const {
726
+ #ifdef __sun__
727
+ string path = dir;
728
+ path.append("/");
729
+ path.append(entry->d_name);
730
+ return getFileType(path) == FT_DIRECTORY;
731
+ #else
732
+ return entry->d_type == DT_DIR;
733
+ #endif
734
+ }
735
+
736
+ bool looksLikeNumber(const char *str) const {
737
+ const char *current = str;
738
+ while (*current != '\0') {
739
+ char c = *current;
740
+ if (!(c >= '0' && c <= '9')) {
741
+ return false;
742
+ }
743
+ current++;
744
+ }
745
+ return true;
746
+ }
747
+
748
+ bool getLastEntryInDirectory(const string &path, string &result) const {
749
+ DIR *dir = opendir(path.c_str());
750
+ struct dirent *entry;
751
+ vector<string> subdirs;
752
+
753
+ if (dir == NULL) {
754
+ int e = errno;
755
+ throw FileSystemException("Cannot open directory " + path,
756
+ e, path);
757
+ }
758
+ while ((entry = readdir(dir)) != NULL) {
759
+ if (isDirectory(path, entry) && looksLikeNumber(entry->d_name)) {
760
+ subdirs.push_back(entry->d_name);
761
+ }
762
+ }
763
+ closedir(dir);
764
+
765
+ if (subdirs.empty()) {
766
+ return false;
767
+ }
768
+
769
+ vector<string>::const_iterator it = subdirs.begin();
770
+ vector<string>::const_iterator end = subdirs.end();
771
+ vector<string>::const_iterator largest_it = subdirs.begin();
772
+ int largest = atoi(subdirs[0]);
773
+ for (it++; it != end; it++) {
774
+ const string &subdir = *it;
775
+ int number = atoi(subdir.c_str());
776
+ if (number > largest) {
777
+ largest_it = it;
778
+ largest = number;
779
+ }
780
+ }
781
+ result = *largest_it;
782
+ return true;
783
+ }
784
+
785
+ static void pendingDataFlushed(EventedClient *_client) {
786
+ Client *client = (Client *) _client;
787
+ LoggingServer *self = (LoggingServer *) client->userData;
788
+
789
+ client->onPendingDataFlushed = NULL;
790
+ if (OXT_UNLIKELY( client->type != WATCHER )) {
791
+ P_WARN("BUG: pendingDataFlushed() called even though client type is not WATCHER.");
792
+ client->disconnect();
793
+ } else if (self->changeNotifier != NULL) {
794
+ self->changeNotifier->addClient(client->detach());
795
+ } else {
796
+ client->disconnect();
797
+ }
798
+ }
799
+
800
+ /* Release all inactive log sinks that have been inactive for more than
801
+ * GARBAGE_COLLECTION_TIMEOUT seconds.
802
+ */
803
+ void releaseInactiveLogSinks(ev_tstamp now) {
804
+ bool done = false;
805
+
806
+ while (!done && !inactiveLogSinks.empty()) {
807
+ const LogSinkPtr logSink = inactiveLogSinks.front();
808
+ if (now - logSink->lastUsed >= GARBAGE_COLLECTION_TIMEOUT) {
809
+ inactiveLogSinks.pop_front();
810
+ inactiveLogSinksCount--;
811
+ logSinkCache.erase(logSink->cacheIterator);
812
+ } else {
813
+ done = true;
814
+ }
815
+ }
816
+ }
817
+
818
+ void garbageCollect(ev::timer &timer, int revents) {
819
+ P_DEBUG("Garbage collection time");
820
+ releaseInactiveLogSinks(ev_now(getLoop()));
821
+ }
822
+
823
+ void sinkFlushTimeout(ev::timer &timer, int revents) {
824
+ P_TRACE(2, "Flushing all sinks (periodic action)");
825
+ LogSinkCache::iterator it;
826
+ LogSinkCache::iterator end = logSinkCache.end();
827
+ ev_tstamp now = ev_now(getLoop());
828
+
829
+ for (it = logSinkCache.begin(); it != end; it++) {
830
+ LogSink *sink = it->second.get();
831
+
832
+ // Flush log file sinks every 15 seconds,
833
+ // remote sinks every 60 seconds.
834
+ if (sink->isRemote()) {
835
+ if (now - sink->lastFlushed >= 60) {
836
+ sink->flush();
837
+ }
838
+ } else {
839
+ sink->flush();
840
+ }
841
+ }
842
+ }
843
+
844
+ void flushAllSinks() {
845
+ P_TRACE(2, "Flushing all sinks");
846
+ LogSinkCache::iterator it;
847
+ LogSinkCache::iterator end = logSinkCache.end();
848
+
849
+ for (it = logSinkCache.begin(); it != end; it++) {
850
+ LogSink *sink = it->second.get();
851
+ sink->flush();
852
+ }
853
+ }
854
+
855
+ void exitTimerTimeout(ev::timer &timer, int revents) {
856
+ if (SystemTime::getMsec() >= exitBeginTime + 5000) {
857
+ exitTimer.stop();
858
+ exitRequested = false;
859
+ refuseNewConnections = false;
860
+ ev_unloop(getLoop(), EVUNLOOP_ONE);
861
+ }
862
+ }
863
+
864
+ protected:
865
+ virtual EventedClient *createClient(const FileDescriptor &fd) {
866
+ return new Client(getLoop(), fd);
867
+ }
868
+
869
+ virtual bool onMessageReceived(EventedMessageClient *_client, const vector<StaticString> &args) {
870
+ Client *client = (Client *) _client;
871
+
872
+ if (args[0] == "log") {
873
+ if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 3)
874
+ || !expectingLoggerType(client) )) {
875
+ return true;
876
+ }
877
+
878
+ string txnId = args[1];
879
+ string timestamp = args[2];
880
+
881
+ TransactionMap::iterator it = transactions.find(txnId);
882
+ if (OXT_UNLIKELY( it == transactions.end() )) {
883
+ sendErrorToClient(client, "Cannot log data: transaction does not exist");
884
+ client->disconnect();
885
+ } else {
886
+ set<string>::iterator sit = client->openTransactions.find(txnId);
887
+ if (OXT_UNLIKELY( sit == client->openTransactions.end() )) {
888
+ sendErrorToClient(client,
889
+ "Cannot log data: transaction not opened in this connection");
890
+ client->disconnect();
891
+ return true;
892
+ }
893
+ // Expecting the log data in a scalar message.
894
+ client->currentTransaction = it->second;
895
+ client->currentTimestamp = timestamp;
896
+ return false;
897
+ }
898
+
899
+ } else if (args[0] == "openTransaction") {
900
+ if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 8)
901
+ || !expectingLoggerType(client) )) {
902
+ return true;
903
+ }
904
+
905
+ string txnId = args[1];
906
+ StaticString groupName = args[2];
907
+ StaticString nodeName = args[3];
908
+ StaticString category = args[4];
909
+ StaticString timestamp = args[5];
910
+ StaticString unionStationKey = args[6];
911
+ bool crashProtect = args[7] == "true";
912
+
913
+ if (OXT_UNLIKELY( !validTxnId(txnId) )) {
914
+ sendErrorToClient(client, "Invalid transaction ID format");
915
+ client->disconnect();
916
+ return true;
917
+ }
918
+ if (!unionStationKey.empty()
919
+ && OXT_UNLIKELY( !validUnionStationKey(unionStationKey) )) {
920
+ sendErrorToClient(client, "Invalid Union Station key format");
921
+ client->disconnect();
922
+ return true;
923
+ }
924
+ if (OXT_UNLIKELY( client->openTransactions.find(txnId) !=
925
+ client->openTransactions.end() ))
926
+ {
927
+ sendErrorToClient(client, "Cannot open transaction: transaction already opened in this connection");
928
+ client->disconnect();
929
+ return true;
930
+ }
931
+
932
+ const char *nodeId;
933
+
934
+ if (nodeName.empty()) {
935
+ nodeName = client->nodeName;
936
+ nodeId = client->nodeId;
937
+ } else {
938
+ nodeId = NULL;
939
+ }
940
+
941
+ TransactionMap::iterator it = transactions.find(txnId);
942
+ TransactionPtr transaction;
943
+ if (it == transactions.end()) {
944
+ if (OXT_UNLIKELY( !supportedCategory(category) )) {
945
+ sendErrorToClient(client, "Unsupported category");
946
+ client->disconnect();
947
+ return true;
948
+ }
949
+
950
+ transaction.reset(new Transaction(this));
951
+ if (unionStationKey.empty()) {
952
+ char tempNodeId[MD5_HEX_SIZE];
953
+
954
+ if (nodeId == NULL) {
955
+ md5_state_t state;
956
+ md5_byte_t digest[MD5_SIZE];
957
+
958
+ md5_init(&state);
959
+ md5_append(&state,
960
+ (const md5_byte_t *) nodeName.data(),
961
+ nodeName.size());
962
+ md5_finish(&state, digest);
963
+ toHex(StaticString((const char *) digest, MD5_SIZE),
964
+ tempNodeId);
965
+ nodeId = tempNodeId;
966
+ }
967
+
968
+ string filename = determineFilename(groupName, nodeId,
969
+ category, txnId);
970
+ if (!openLogFileWithCache(filename, transaction->logSink)) {
971
+ setupGroupAndNodeDir(groupName, nodeName, nodeId);
972
+ }
973
+ } else {
974
+ openRemoteSink(unionStationKey, client->nodeName,
975
+ category, transaction->logSink);
976
+ }
977
+ transaction->txnId = txnId;
978
+ transaction->dataStoreId = DataStoreId(groupName,
979
+ nodeName, category);
980
+ transaction->writeCount = 0;
981
+ transaction->refcount = 0;
982
+ transaction->crashProtect = crashProtect;
983
+ transaction->discarded = false;
984
+ transactions.insert(make_pair(txnId, transaction));
985
+ } else {
986
+ transaction = it->second;
987
+ if (OXT_UNLIKELY( transaction->getGroupName() != groupName )) {
988
+ sendErrorToClient(client,
989
+ "Cannot open transaction: transaction already opened with a different group name");
990
+ client->disconnect();
991
+ return true;
992
+ }
993
+ if (OXT_UNLIKELY( transaction->getNodeName() != nodeName )) {
994
+ sendErrorToClient(client,
995
+ "Cannot open transaction: transaction already opened with a different node name");
996
+ client->disconnect();
997
+ return true;
998
+ }
999
+ if (OXT_UNLIKELY( transaction->getCategory() != category )) {
1000
+ sendErrorToClient(client,
1001
+ "Cannot open transaction: transaction already opened with a different category name");
1002
+ client->disconnect();
1003
+ return true;
1004
+ }
1005
+ }
1006
+
1007
+ client->openTransactions.insert(txnId);
1008
+ transaction->refcount++;
1009
+ writeLogEntry(client, transaction, timestamp, "ATTACH");
1010
+
1011
+ } else if (args[0] == "closeTransaction") {
1012
+ if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 3)
1013
+ || !expectingLoggerType(client) )) {
1014
+ return true;
1015
+ }
1016
+
1017
+ string txnId = args[1];
1018
+ StaticString timestamp = args[2];
1019
+
1020
+ TransactionMap::iterator it = transactions.find(txnId);
1021
+ if (OXT_UNLIKELY( it == transactions.end() )) {
1022
+ sendErrorToClient(client,
1023
+ "Cannot close transaction " + txnId +
1024
+ ": transaction does not exist");
1025
+ client->disconnect();
1026
+ } else {
1027
+ TransactionPtr &transaction = it->second;
1028
+
1029
+ set<string>::const_iterator sit = client->openTransactions.find(txnId);
1030
+ if (OXT_UNLIKELY( sit == client->openTransactions.end() )) {
1031
+ sendErrorToClient(client,
1032
+ "Cannot close transaction " + txnId +
1033
+ ": transaction not opened in this connection");
1034
+ client->disconnect();
1035
+ return true;
1036
+ } else {
1037
+ client->openTransactions.erase(sit);
1038
+ }
1039
+
1040
+ writeDetachEntry(client, transaction, timestamp);
1041
+ transaction->refcount--;
1042
+ assert(transaction->refcount >= 0);
1043
+ if (transaction->refcount == 0) {
1044
+ transactions.erase(it);
1045
+ }
1046
+ }
1047
+
1048
+ } else if (args[0] == "init") {
1049
+ if (OXT_UNLIKELY( client->type != UNINITIALIZED )) {
1050
+ sendErrorToClient(client, "Already initialized");
1051
+ client->disconnect();
1052
+ return true;
1053
+ }
1054
+ if (OXT_UNLIKELY( !expectingArgumentsCount(client, args, 2) )) {
1055
+ return true;
1056
+ }
1057
+ if (OXT_UNLIKELY( !checkWhetherConnectionAreAcceptable(client) )) {
1058
+ return true;
1059
+ }
1060
+
1061
+ StaticString nodeName = args[1];
1062
+ client->nodeName = nodeName;
1063
+
1064
+ md5_state_t state;
1065
+ md5_byte_t digest[MD5_SIZE];
1066
+ md5_init(&state);
1067
+ md5_append(&state, (const md5_byte_t *) nodeName.data(), nodeName.size());
1068
+ md5_finish(&state, digest);
1069
+ toHex(StaticString((const char *) digest, MD5_SIZE), client->nodeId);
1070
+
1071
+ client->type = LOGGER;
1072
+ client->writeArrayMessage("ok", NULL);
1073
+
1074
+ } else if (args[0] == "watchChanges") {
1075
+ if (OXT_UNLIKELY( !checkWhetherConnectionAreAcceptable(client) )) {
1076
+ return true;
1077
+ }
1078
+ if (OXT_UNLIKELY( client->type != UNINITIALIZED )) {
1079
+ sendErrorToClient(client, "This command cannot be invoked "
1080
+ "if the 'init' command is already invoked.");
1081
+ client->disconnect();
1082
+ return true;
1083
+ }
1084
+
1085
+ client->type = WATCHER;
1086
+ client->notifyReads(false);
1087
+ discardReadData();
1088
+
1089
+ // Add to the change notifier after all pending data
1090
+ // has been written out.
1091
+ client->onPendingDataFlushed = pendingDataFlushed;
1092
+ client->writeArrayMessage("ok", NULL);
1093
+
1094
+ } else if (args[0] == "flush") {
1095
+ flushAllSinks();
1096
+ client->writeArrayMessage("ok", NULL);
1097
+
1098
+ } else if (args[0] == "info") {
1099
+ stringstream stream;
1100
+ dump(stream);
1101
+ client->writeArrayMessage("info", stream.str().c_str(), NULL);
1102
+
1103
+ } else if (args[0] == "ping") {
1104
+ client->writeArrayMessage("pong", NULL);
1105
+
1106
+ } else if (args[0] == "exit") {
1107
+ if (!requireRights(client, Account::EXIT)) {
1108
+ client->disconnect();
1109
+ return true;
1110
+ }
1111
+ if (args.size() == 2 && args[1] == "immediately") {
1112
+ // Immediate exit.
1113
+ ev_unloop(getLoop(), EVUNLOOP_ONE);
1114
+ } else if (args.size() == 2 && args[1] == "semi-gracefully") {
1115
+ // Semi-graceful exit: refuse new connections, shut down
1116
+ // a few seconds after the last client has disconnected.
1117
+ refuseNewConnections = true;
1118
+ exitRequested = true;
1119
+ } else {
1120
+ // Graceful exit: shut down a few seconds after the
1121
+ // last client has disconnected.
1122
+ client->writeArrayMessage("Passed security", NULL);
1123
+ client->writeArrayMessage("exit command received", NULL);
1124
+ exitRequested = true;
1125
+ }
1126
+ client->disconnect();
1127
+
1128
+ } else {
1129
+ sendErrorToClient(client, "Unknown command '" + args[0] + "'");
1130
+ client->disconnect();
1131
+ }
1132
+
1133
+ return true;
1134
+ }
1135
+
1136
+ virtual pair<size_t, bool> onOtherDataReceived(EventedMessageClient *_client,
1137
+ const char *data, size_t size)
1138
+ {
1139
+ // In here we read the scalar message that's expected to come
1140
+ // after the "log" command.
1141
+ Client *client = (Client *) _client;
1142
+ size_t consumed = client->dataReader.feed(data, size);
1143
+ if (client->dataReader.done()) {
1144
+ writeLogEntry(client,
1145
+ client->currentTransaction,
1146
+ client->currentTimestamp,
1147
+ client->dataReader.value());
1148
+ client->currentTransaction.reset();
1149
+ client->dataReader.reset();
1150
+ return make_pair(consumed, true);
1151
+ } else {
1152
+ return make_pair(consumed, false);
1153
+ }
1154
+ }
1155
+
1156
+ virtual void onNewClient(EventedClient *client) {
1157
+ if (exitRequested && exitTimer.is_active()) {
1158
+ exitTimer.stop();
1159
+ }
1160
+ EventedMessageServer::onNewClient(client);
1161
+ }
1162
+
1163
+ virtual void onClientDisconnected(EventedClient *_client) {
1164
+ EventedMessageServer::onClientDisconnected(_client);
1165
+ Client *client = (Client *) _client;
1166
+ set<string>::const_iterator sit;
1167
+ set<string>::const_iterator send = client->openTransactions.end();
1168
+
1169
+ // Close any transactions that this client had opened.
1170
+ for (sit = client->openTransactions.begin(); sit != send; sit++) {
1171
+ const string &txnId = *sit;
1172
+ TransactionMap::iterator it = transactions.find(txnId);
1173
+ if (OXT_UNLIKELY( it == transactions.end() )) {
1174
+ P_ERROR("Bug: client->openTransactions is not a subset of this->transactions!");
1175
+ abort();
1176
+ }
1177
+
1178
+ TransactionPtr &transaction = it->second;
1179
+ if (transaction->crashProtect) {
1180
+ writeDetachEntry(client, transaction);
1181
+ } else {
1182
+ transaction->discard();
1183
+ }
1184
+ transaction->refcount--;
1185
+ assert(transaction->refcount >= 0);
1186
+ if (transaction->refcount == 0) {
1187
+ transactions.erase(it);
1188
+ }
1189
+ }
1190
+ client->openTransactions.clear();
1191
+
1192
+ // Possibly start exit timer.
1193
+ if (exitRequested && getClients().empty()) {
1194
+ exitTimer.start();
1195
+ /* Using SystemTime here instead of setting a correct
1196
+ * timeout directly on the timer, so that we can
1197
+ * manipulate the clock in LoggingServer unit tests.
1198
+ */
1199
+ exitBeginTime = SystemTime::getMsec();
1200
+ }
1201
+ }
1202
+
1203
+ public:
1204
+ LoggingServer(struct ev_loop *loop,
1205
+ FileDescriptor fd,
1206
+ const AccountsDatabasePtr &accountsDatabase,
1207
+ const string &dir,
1208
+ const string &permissions = DEFAULT_ANALYTICS_LOG_PERMISSIONS,
1209
+ gid_t gid = GROUP_NOT_GIVEN,
1210
+ const string &unionStationGatewayAddress = DEFAULT_UNION_STATION_GATEWAY_ADDRESS,
1211
+ unsigned short unionStationGatewayPort = DEFAULT_UNION_STATION_GATEWAY_PORT,
1212
+ const string &unionStationGatewayCert = "")
1213
+ : EventedMessageServer(loop, fd, accountsDatabase),
1214
+ remoteSender(unionStationGatewayAddress,
1215
+ unionStationGatewayPort,
1216
+ unionStationGatewayCert),
1217
+ garbageCollectionTimer(loop),
1218
+ sinkFlushingTimer(loop),
1219
+ exitTimer(loop)
1220
+ {
1221
+ this->dir = dir;
1222
+ this->gid = gid;
1223
+ dirPermissions = permissions;
1224
+ filePermissions = parseModeString(permissions) & ~(S_IXUSR | S_IXGRP | S_IXOTH);
1225
+ garbageCollectionTimer.set<LoggingServer, &LoggingServer::garbageCollect>(this);
1226
+ garbageCollectionTimer.start(GARBAGE_COLLECTION_TIMEOUT, GARBAGE_COLLECTION_TIMEOUT);
1227
+ sinkFlushingTimer.set<LoggingServer, &LoggingServer::sinkFlushTimeout>(this);
1228
+ sinkFlushingTimer.start(15, 15);
1229
+ exitTimer.set<LoggingServer, &LoggingServer::exitTimerTimeout>(this);
1230
+ exitTimer.set(0.05, 0.05);
1231
+ refuseNewConnections = false;
1232
+ exitRequested = false;
1233
+ inactiveLogSinksCount = 0;
1234
+ }
1235
+
1236
+ ~LoggingServer() {
1237
+ TransactionMap::iterator it, end = transactions.end();
1238
+ for (it = transactions.begin(); it != end; it++) {
1239
+ TransactionPtr &transaction = it->second;
1240
+ if (transaction->crashProtect) {
1241
+ writeDetachEntry(NULL, transaction);
1242
+ } else {
1243
+ transaction->discard();
1244
+ }
1245
+ }
1246
+
1247
+ // Invoke destructors, causing all transactions and log sinks to
1248
+ // be flushed before RemoteSender and ChangeNotifier are being
1249
+ // destroyed.
1250
+ transactions.clear();
1251
+ logSinkCache.clear();
1252
+ inactiveLogSinks.clear();
1253
+ }
1254
+
1255
+ void setChangeNotifier(const ChangeNotifierPtr &_changeNotifier) {
1256
+ changeNotifier = _changeNotifier;
1257
+ changeNotifier->getLastPos = boost::bind(&LoggingServer::getLastPos,
1258
+ this, _1, _2, _3);
1259
+ }
1260
+
1261
+ string getLastPos(const StaticString &groupName, const StaticString &nodeName,
1262
+ const StaticString &category) const
1263
+ {
1264
+ md5_state_t state;
1265
+ md5_byte_t digest[MD5_SIZE];
1266
+ char nodeId[MD5_HEX_SIZE];
1267
+ md5_init(&state);
1268
+ md5_append(&state, (const md5_byte_t *) nodeName.data(), nodeName.size());
1269
+ md5_finish(&state, digest);
1270
+ toHex(StaticString((const char *) digest, MD5_SIZE), nodeId);
1271
+
1272
+ string dir = determineFilename(groupName, nodeId, category);
1273
+ string subdir, component;
1274
+ subdir.reserve(13); // It's a string that looks like: "2010/06/24/12"
1275
+
1276
+ try {
1277
+ // Loop 4 times to process year, month, day, hour.
1278
+ for (int i = 0; i < 4; i++) {
1279
+ bool found = getLastEntryInDirectory(dir, component);
1280
+ if (!found) {
1281
+ return string();
1282
+ }
1283
+ dir.append("/");
1284
+ dir.append(component);
1285
+ if (i != 0) {
1286
+ subdir.append("/");
1287
+ }
1288
+ subdir.append(component);
1289
+ }
1290
+ // After the loop, new dir == old dir + "/" + subdir
1291
+ } catch (const SystemException &e) {
1292
+ if (e.code() == ENOENT) {
1293
+ return string();
1294
+ } else {
1295
+ throw;
1296
+ }
1297
+ }
1298
+
1299
+ string &filename = dir;
1300
+ filename.append("/log.txt");
1301
+
1302
+ struct stat buf;
1303
+ if (stat(filename.c_str(), &buf) == -1) {
1304
+ if (errno == ENOENT) {
1305
+ return string();
1306
+ } else {
1307
+ int e = errno;
1308
+ throw FileSystemException("Cannot stat() " + filename, e,
1309
+ filename);
1310
+ }
1311
+ } else {
1312
+ return subdir + "/" + toString(buf.st_size);
1313
+ }
1314
+ }
1315
+
1316
+ void dump(ostream &stream) const {
1317
+ TransactionMap::const_iterator it;
1318
+ TransactionMap::const_iterator end = transactions.end();
1319
+
1320
+ stream << "Number of clients: " << getClients().size() << "\n";
1321
+ stream << "Open transactions: " << transactions.size() << "\n";
1322
+ for (it = transactions.begin(); it != end; it++) {
1323
+ const TransactionPtr &transaction = it->second;
1324
+ transaction->dump(stream);
1325
+ }
1326
+
1327
+ LogSinkCache::const_iterator sit;
1328
+ LogSinkCache::const_iterator send = logSinkCache.end();
1329
+ stream << "Log sinks: " << logSinkCache.size() <<
1330
+ " (" << inactiveLogSinksCount << " inactive)\n";
1331
+ for (sit = logSinkCache.begin(); sit != send; sit++) {
1332
+ const LogSinkPtr &logSink = sit->second;
1333
+ logSink->dump(stream);
1334
+ }
1335
+ }
1336
+ };
1337
+
1338
+ typedef shared_ptr<LoggingServer> LoggingServerPtr;
1339
+
1340
+
1341
+ } // namespace Passenger
1342
+
1343
+ #endif /* _PASSENGER_LOGGING_SERVER_H_ */