passenger 2.2.2 → 2.2.3

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 (254) hide show
  1. data/DEVELOPERS.TXT +13 -3
  2. data/Rakefile +42 -33
  3. data/bin/passenger-install-apache2-module +1 -2
  4. data/bin/passenger-install-nginx-module +7 -19
  5. data/bin/passenger-status +64 -15
  6. data/bin/passenger-stress-test +2 -2
  7. data/doc/ApplicationPool algorithm.txt +26 -22
  8. data/doc/Users guide Apache.html +374 -149
  9. data/doc/Users guide Apache.txt +318 -51
  10. data/doc/Users guide Nginx.html +13 -13
  11. data/doc/Users guide Nginx.txt +7 -2
  12. data/doc/cxxapi/Bucket_8h-source.html +62 -25
  13. data/doc/cxxapi/Configuration_8h-source.html +343 -326
  14. data/doc/cxxapi/DirectoryMapper_8h-source.html +12 -12
  15. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  16. data/doc/cxxapi/annotated.html +1 -1
  17. data/doc/cxxapi/classHooks-members.html +1 -1
  18. data/doc/cxxapi/classHooks.html +1 -1
  19. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +2 -2
  20. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +9 -9
  21. data/doc/cxxapi/classes.html +1 -1
  22. data/doc/cxxapi/definitions_8h-source.html +1 -1
  23. data/doc/cxxapi/files.html +1 -1
  24. data/doc/cxxapi/functions.html +2 -2
  25. data/doc/cxxapi/functions_func.html +2 -2
  26. data/doc/cxxapi/graph_legend.html +1 -1
  27. data/doc/cxxapi/group__Configuration.html +1 -1
  28. data/doc/cxxapi/group__Core.html +1 -1
  29. data/doc/cxxapi/group__Hooks.html +1 -1
  30. data/doc/cxxapi/group__Support.html +1 -1
  31. data/doc/cxxapi/main.html +1 -1
  32. data/doc/cxxapi/modules.html +1 -1
  33. data/doc/rdoc/classes/ConditionVariable.html +194 -0
  34. data/doc/rdoc/classes/Exception.html +120 -0
  35. data/doc/rdoc/classes/GC.html +113 -0
  36. data/doc/rdoc/classes/IO.html +169 -0
  37. data/doc/rdoc/classes/PhusionPassenger.html +238 -0
  38. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +153 -0
  39. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +517 -0
  40. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +719 -0
  41. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +97 -0
  42. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +96 -0
  43. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +97 -0
  44. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +96 -0
  45. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
  46. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
  47. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +317 -0
  48. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
  49. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +154 -0
  50. data/doc/rdoc/classes/PhusionPassenger/Application.html +283 -0
  51. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +172 -0
  52. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +145 -0
  53. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +175 -0
  54. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +141 -0
  55. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  56. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +489 -0
  57. data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +350 -0
  58. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  59. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +188 -0
  60. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +194 -0
  61. data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
  62. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +442 -0
  63. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
  64. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
  65. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +436 -0
  66. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
  67. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +155 -0
  68. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +402 -0
  69. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +125 -0
  70. data/doc/rdoc/classes/PhusionPassenger/Utils.html +805 -0
  71. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +140 -0
  72. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  73. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
  74. data/doc/rdoc/classes/PlatformInfo.html +831 -0
  75. data/doc/rdoc/classes/RakeExtensions.html +197 -0
  76. data/doc/rdoc/classes/Signal.html +131 -0
  77. data/doc/rdoc/created.rid +1 -0
  78. data/doc/rdoc/files/DEVELOPERS_TXT.html +255 -0
  79. data/doc/rdoc/files/README.html +157 -0
  80. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +92 -0
  81. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +129 -0
  82. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +131 -0
  83. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +126 -0
  84. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +130 -0
  85. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +130 -0
  86. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +122 -0
  87. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +127 -0
  88. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +126 -0
  89. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +122 -0
  90. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +134 -0
  91. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +122 -0
  92. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +122 -0
  93. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +126 -0
  94. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +122 -0
  95. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
  96. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +127 -0
  97. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +133 -0
  98. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +127 -0
  99. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +143 -0
  100. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
  101. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +145 -0
  102. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +127 -0
  103. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +122 -0
  104. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +161 -0
  105. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +175 -0
  106. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +129 -0
  107. data/doc/rdoc/files/misc/rake/extensions_rb.html +130 -0
  108. data/doc/rdoc/fr_class_index.html +90 -0
  109. data/doc/rdoc/fr_file_index.html +76 -0
  110. data/doc/rdoc/fr_method_index.html +200 -0
  111. data/doc/rdoc/index.html +26 -0
  112. data/doc/rdoc/rdoc-style.css +187 -0
  113. data/doc/users_guide_snippets/rackup_specifications.txt +2 -8
  114. data/ext/apache2/Bucket.cpp +71 -38
  115. data/ext/apache2/Bucket.h +53 -16
  116. data/ext/apache2/Configuration.cpp +15 -0
  117. data/ext/apache2/Configuration.h +19 -2
  118. data/ext/apache2/DirectoryMapper.h +10 -10
  119. data/ext/apache2/Hooks.cpp +334 -74
  120. data/ext/boost/mpl/apply.hpp +5 -1
  121. data/ext/boost/mpl/apply_wrap.hpp +5 -2
  122. data/ext/boost/mpl/aux_/full_lambda.hpp +5 -1
  123. data/ext/boost/mpl/bind.hpp +5 -1
  124. data/ext/common/Application.h +11 -31
  125. data/ext/common/ApplicationPool.h +2 -1
  126. data/ext/common/ApplicationPoolServer.h +61 -20
  127. data/ext/common/ApplicationPoolServerExecutable.cpp +132 -4
  128. data/ext/common/ApplicationPoolStatusReporter.h +189 -65
  129. data/ext/common/Base64.cpp +143 -0
  130. data/ext/common/Base64.h +57 -0
  131. data/ext/common/CachedFileStat.cpp +25 -82
  132. data/ext/common/CachedFileStat.h +11 -125
  133. data/ext/common/CachedFileStat.hpp +243 -0
  134. data/ext/common/Exceptions.h +13 -0
  135. data/ext/common/FileChangeChecker.h +209 -0
  136. data/ext/common/Logging.h +3 -2
  137. data/ext/common/MessageChannel.h +10 -10
  138. data/ext/common/PoolOptions.h +72 -5
  139. data/ext/common/SpawnManager.h +11 -8
  140. data/ext/common/StandardApplicationPool.h +38 -39
  141. data/ext/common/StaticString.h +1 -0
  142. data/ext/common/StringListCreator.h +83 -0
  143. data/ext/common/SystemTime.h +3 -2
  144. data/ext/common/Timer.h +88 -0
  145. data/ext/common/Utils.cpp +161 -42
  146. data/ext/common/Utils.h +62 -31
  147. data/ext/common/Version.h +1 -1
  148. data/ext/nginx/Configuration.c +0 -4
  149. data/ext/nginx/ContentHandler.c +8 -6
  150. data/ext/nginx/HelperServer.cpp +45 -55
  151. data/ext/nginx/HttpStatusExtractor.h +4 -0
  152. data/ext/nginx/StaticContentHandler.c +25 -5
  153. data/ext/nginx/config +3 -0
  154. data/ext/nginx/ngx_http_passenger_module.c +72 -17
  155. data/ext/nginx/ngx_http_passenger_module.h +2 -2
  156. data/lib/phusion_passenger/abstract_request_handler.rb +15 -7
  157. data/lib/phusion_passenger/abstract_server.rb +16 -2
  158. data/lib/phusion_passenger/admin_tools/control_process.rb +36 -25
  159. data/lib/phusion_passenger/constants.rb +1 -1
  160. data/lib/phusion_passenger/dependencies.rb +10 -0
  161. data/lib/phusion_passenger/platform_info.rb +1 -1
  162. data/lib/phusion_passenger/rack/application_spawner.rb +21 -2
  163. data/lib/phusion_passenger/rack/request_handler.rb +10 -0
  164. data/lib/phusion_passenger/railz/application_spawner.rb +38 -2
  165. data/lib/phusion_passenger/railz/framework_spawner.rb +26 -28
  166. data/lib/phusion_passenger/railz/request_handler.rb +5 -1
  167. data/lib/phusion_passenger/spawn_manager.rb +6 -2
  168. data/lib/phusion_passenger/utils.rb +79 -27
  169. data/misc/rake/cplusplus.rb +5 -5
  170. data/test/ApplicationPoolServerTest.cpp +42 -0
  171. data/test/ApplicationPoolTest.cpp +255 -267
  172. data/test/Base64Test.cpp +48 -0
  173. data/test/CachedFileStatTest.cpp +243 -103
  174. data/test/FileChangeCheckerTest.cpp +331 -0
  175. data/test/PoolOptionsTest.cpp +80 -0
  176. data/test/UtilsTest.cpp +5 -17
  177. data/test/integration_tests/apache2_tests.rb +15 -4
  178. data/test/integration_tests/mycook_spec.rb +3 -4
  179. data/test/oxt/syscall_interruption_test.cpp +2 -14
  180. data/test/ruby/abstract_server_collection_spec.rb +1 -1
  181. data/test/ruby/abstract_server_spec.rb +35 -1
  182. data/test/ruby/rack/application_spawner_spec.rb +23 -6
  183. data/test/ruby/rails/application_spawner_spec.rb +6 -6
  184. data/test/ruby/rails/framework_spawner_spec.rb +6 -5
  185. data/test/ruby/rails/minimal_spawner_spec.rb +19 -0
  186. data/test/ruby/rails/spawner_error_handling_spec.rb +62 -7
  187. data/test/ruby/spawn_manager_spec.rb +10 -7
  188. data/test/ruby/spawn_server_spec.rb +1 -1
  189. data/test/ruby/utils_spec.rb +193 -20
  190. data/test/ruby/wsgi/application_spawner_spec.rb +3 -1
  191. data/test/stub/apache2/httpd.conf.erb +3 -0
  192. data/test/stub/rack/config.ru +1 -1
  193. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +8 -0
  194. data/test/support/Support.cpp +84 -0
  195. data/test/support/Support.h +66 -8
  196. data/test/support/config.rb +14 -2
  197. data/test/support/test_helper.rb +5 -0
  198. data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +123 -116
  199. data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +17 -12
  200. data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +34 -43
  201. data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +1 -1
  202. data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +1 -1
  203. data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +1 -1
  204. data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +1 -1
  205. data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +1 -1
  206. data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +1 -1
  207. data/vendor/rack-1.0.0-git/lib/rack/mock.rb +4 -17
  208. data/vendor/rack-1.0.0-git/lib/rack/request.rb +3 -9
  209. data/vendor/rack-1.0.0-git/lib/rack/rewindable_input.rb +2 -0
  210. data/vendor/rack-1.0.0-git/lib/rack/utils.rb +38 -12
  211. metadata +231 -186
  212. data/ext/common/FileChecker.h +0 -112
  213. data/test/FileCheckerTest.cpp +0 -79
  214. data/test/stub/minimal-railsapp/README +0 -3
  215. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  216. data/test/stub/minimal-railsapp/config/environment.rb +0 -3
  217. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  218. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -10
  219. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  220. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  221. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -7
  222. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  223. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -17
  224. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  225. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  226. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -8
  227. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -1
  228. data/test/stub/railsapp/app/controllers/application.rb +0 -12
  229. data/test/stub/railsapp/app/controllers/bar_controller.rb +0 -5
  230. data/test/stub/railsapp/app/controllers/bar_controller_1.txt +0 -5
  231. data/test/stub/railsapp/app/controllers/bar_controller_2.txt +0 -5
  232. data/test/stub/railsapp/app/controllers/foo_controller.rb +0 -9
  233. data/test/stub/railsapp/app/helpers/application_helper.rb +0 -3
  234. data/test/stub/railsapp/config/boot.rb +0 -108
  235. data/test/stub/railsapp/config/database.yml +0 -19
  236. data/test/stub/railsapp/config/environment.rb +0 -59
  237. data/test/stub/railsapp/config/environments/development.rb +0 -18
  238. data/test/stub/railsapp/config/environments/production.rb +0 -19
  239. data/test/stub/railsapp/config/initializers/inflections.rb +0 -10
  240. data/test/stub/railsapp/config/initializers/mime_types.rb +0 -5
  241. data/test/stub/railsapp/config/routes.rb +0 -35
  242. data/test/stub/railsapp/public/useless.txt +0 -1
  243. data/test/stub/railsapp2/app/controllers/application.rb +0 -12
  244. data/test/stub/railsapp2/app/controllers/foo_controller.rb +0 -5
  245. data/test/stub/railsapp2/app/helpers/application_helper.rb +0 -3
  246. data/test/stub/railsapp2/config/boot.rb +0 -108
  247. data/test/stub/railsapp2/config/database.yml +0 -19
  248. data/test/stub/railsapp2/config/environment.rb +0 -59
  249. data/test/stub/railsapp2/config/environments/development.rb +0 -18
  250. data/test/stub/railsapp2/config/environments/production.rb +0 -19
  251. data/test/stub/railsapp2/config/initializers/inflections.rb +0 -10
  252. data/test/stub/railsapp2/config/initializers/mime_types.rb +0 -5
  253. data/test/stub/railsapp2/config/routes.rb +0 -35
  254. data/test/stub/railsapp2/public/useless.txt +0 -1
@@ -0,0 +1,26 @@
1
+
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <title>Passenger Ruby API</title>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
9
+ </head>
10
+
11
+ <frameset cols="20%,*">
12
+ <frameset rows="15%,55%,30%">
13
+ <frame src="fr_file_index.html" title="Files" name="Files" />
14
+ <frame src="fr_class_index.html" name="Classes" />
15
+ <frame src="fr_method_index.html" name="Methods" />
16
+ </frameset>
17
+ <frame src="files/README.html" name="docwin" />
18
+ <noframes>
19
+ <body bgcolor="white">
20
+ Click <a href="html/index.html">here</a> for a non-frames
21
+ version of this page.
22
+ </body>
23
+ </noframes>
24
+ </frameset>
25
+
26
+ </html>
@@ -0,0 +1,187 @@
1
+ a {
2
+ color: #00F;
3
+ text-decoration: none;
4
+ }
5
+
6
+ a:hover {
7
+ color: #77F;
8
+ text-decoration: underline;
9
+ }
10
+
11
+ body, td, p {
12
+ font-family: "Bitstream Vera Sans", Verdana, Arial, Helvetica, sans-serif;
13
+ background: #FFF;
14
+ color: #000;
15
+ margin: 0px;
16
+ font-size: small;
17
+ }
18
+
19
+ p {
20
+ margin-top: 0.5em;
21
+ margin-bottom: 0.5em;
22
+ }
23
+
24
+ #content {
25
+ margin: 2em;
26
+ margin-left: 3.5em;
27
+ margin-right: 3.5em;
28
+ }
29
+
30
+ #description p {
31
+ margin-bottom: 0.5em;
32
+ }
33
+
34
+ .sectiontitle {
35
+ margin-top: 1em;
36
+ margin-bottom: 1em;
37
+ padding: 0.5em;
38
+ padding-left: 2em;
39
+ background: #005;
40
+ color: #FFF;
41
+ font-weight: bold;
42
+ }
43
+
44
+ .attr-rw {
45
+ padding-left: 1em;
46
+ padding-right: 1em;
47
+ text-align: center;
48
+ color: #055;
49
+ }
50
+
51
+ .attr-name {
52
+ font-weight: bold;
53
+ }
54
+
55
+ .attr-desc {
56
+ }
57
+
58
+ .attr-value {
59
+ font-family: monospace;
60
+ }
61
+
62
+ .file-title-prefix {
63
+ font-size: large;
64
+ }
65
+
66
+ .file-title {
67
+ font-size: large;
68
+ font-weight: bold;
69
+ background: #005;
70
+ color: #FFF;
71
+ }
72
+
73
+ .banner {
74
+ background: #005;
75
+ color: #FFF;
76
+ border: 1px solid black;
77
+ padding: 1em;
78
+ }
79
+
80
+ .banner td {
81
+ background: transparent;
82
+ color: #FFF;
83
+ }
84
+
85
+ h1 a, h2 a, .sectiontitle a, .banner a {
86
+ color: #FF0;
87
+ }
88
+
89
+ h1 a:hover, h2 a:hover, .sectiontitle a:hover, .banner a:hover {
90
+ color: #FF7;
91
+ }
92
+
93
+ .dyn-source {
94
+ display: none;
95
+ background: #fffde8;
96
+ color: #000;
97
+ border: #ffe0bb dotted 1px;
98
+ margin: 0.5em 2em 0.5em 2em;
99
+ padding: 0.5em;
100
+ }
101
+
102
+ .dyn-source .cmt {
103
+ color: #00F;
104
+ font-style: italic;
105
+ }
106
+
107
+ .dyn-source .kw {
108
+ color: #070;
109
+ font-weight: bold;
110
+ }
111
+
112
+ .method {
113
+ margin-left: 1em;
114
+ margin-right: 1em;
115
+ margin-bottom: 1em;
116
+ }
117
+
118
+ .description pre {
119
+ padding: 0.5em;
120
+ border: #ffe0bb dotted 1px;
121
+ background: #fffde8;
122
+ }
123
+
124
+ .method .title {
125
+ font-family: monospace;
126
+ font-size: large;
127
+ border-bottom: 1px dashed black;
128
+ margin-bottom: 0.3em;
129
+ padding-bottom: 0.1em;
130
+ }
131
+
132
+ .method .description, .method .sourcecode {
133
+ margin-left: 1em;
134
+ }
135
+
136
+ .description p, .sourcecode p {
137
+ margin-bottom: 0.5em;
138
+ }
139
+
140
+ .method .sourcecode p.source-link {
141
+ text-indent: 0em;
142
+ margin-top: 0.5em;
143
+ }
144
+
145
+ .method .aka {
146
+ margin-top: 0.3em;
147
+ margin-left: 1em;
148
+ font-style: italic;
149
+ text-indent: 2em;
150
+ }
151
+
152
+ h1 {
153
+ padding: 1em;
154
+ margin-left: -1.5em;
155
+ font-size: x-large;
156
+ font-weight: bold;
157
+ color: #FFF;
158
+ background: #007;
159
+ }
160
+
161
+ h2 {
162
+ padding: 0.5em 1em 0.5em 1em;
163
+ margin-left: -1.5em;
164
+ font-size: large;
165
+ font-weight: bold;
166
+ color: #FFF;
167
+ background: #009;
168
+ }
169
+
170
+ h3, h4, h5, h6 {
171
+ color: #220088;
172
+ border-bottom: #5522bb solid 1px;
173
+ }
174
+
175
+ .sourcecode > pre {
176
+ padding: 0.5em;
177
+ border: 1px dotted black;
178
+ background: #FFE;
179
+ }
180
+
181
+ dt {
182
+ font-weight: bold
183
+ }
184
+
185
+ dd {
186
+ margin-bottom: 0.7em;
187
+ }
@@ -41,7 +41,7 @@ require 'rubygems'
41
41
  require 'merb-core'
42
42
 
43
43
  Merb::Config.setup(
44
- :merb_root => File.expand_path(File.dirname(__FILE__)),
44
+ :merb_root => ::File.expand_path(::File.dirname(__FILE__)),
45
45
  :environment => ENV['RACK_ENV']
46
46
  )
47
47
  Merb.environment = Merb::Config[:environment]
@@ -65,13 +65,7 @@ run Ramaze::Adapter::Base
65
65
  ------------------------------------------------------
66
66
  require 'rubygems'
67
67
  require 'sinatra'
68
-
69
- root_dir = File.dirname(__FILE__)
70
-
71
- set :environment, ENV['RACK_ENV'].to_sym
72
- set :root, root_dir
73
- set :app_file, File.join(root_dir, 'app.rb')
74
- disable :run
68
+ require 'app.rb'
75
69
 
76
70
  run Sinatra::Application
77
71
  ------------------------------------------------------
@@ -24,7 +24,7 @@
24
24
  */
25
25
  #include "Bucket.h"
26
26
 
27
- using namespace Passenger;
27
+ namespace Passenger {
28
28
 
29
29
  static void bucket_destroy(void *data);
30
30
  static apr_status_t bucket_read(apr_bucket *a, const char **str, apr_size_t *len, apr_read_type_e block);
@@ -42,7 +42,24 @@ static const apr_bucket_type_t apr_bucket_type_passenger_pipe = {
42
42
 
43
43
  struct BucketData {
44
44
  Application::SessionPtr session;
45
- apr_file_t *pipe;
45
+ PassengerBucketStatePtr state;
46
+ int stream;
47
+
48
+ ~BucketData() {
49
+ /* The session here is an ApplicationPoolServer::RemoteSession.
50
+ * The only reason why its destructor might fail is when sending
51
+ * the 'close' command failed. We don't care about that, and we
52
+ * don't want C++ exceptions to propagate onto a C stack (this
53
+ * bucket is probably used by Apache's bucket brigade code, which
54
+ * is written in C), so we ignore all errors in the session's
55
+ * destructor.
56
+ */
57
+ try {
58
+ session.reset();
59
+ } catch (const SystemException &e) {
60
+ // Do nothing.
61
+ }
62
+ }
46
63
  };
47
64
 
48
65
  static void
@@ -55,15 +72,13 @@ bucket_destroy(void *data) {
55
72
 
56
73
  static apr_status_t
57
74
  bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type_e block) {
58
- apr_file_t *pipe;
59
75
  char *buf;
60
- apr_status_t ret;
61
-
62
- BucketData *data = (BucketData *) bucket->data;
63
- pipe = data->pipe;
64
-
76
+ ssize_t ret;
77
+ BucketData *data;
78
+
79
+ data = (BucketData *) bucket->data;
65
80
  *str = NULL;
66
- *len = APR_BUCKET_BUFF_SIZE;
81
+ *len = 0;
67
82
 
68
83
  if (block == APR_NONBLOCK_READ) {
69
84
  /*
@@ -85,55 +100,72 @@ bucket_read(apr_bucket *bucket, const char **str, apr_size_t *len, apr_read_type
85
100
  return APR_EAGAIN;
86
101
  }
87
102
 
88
- buf = (char *) apr_bucket_alloc(*len, bucket->list); // TODO: check for failure?
89
-
90
- do {
91
- ret = apr_file_read(pipe, buf, len);
92
- } while (APR_STATUS_IS_EAGAIN(ret));
93
-
94
- if (ret != APR_SUCCESS && ret != APR_EOF) {
95
- // ... we might want to set an error flag here ...
96
- delete data;
97
- bucket->data = NULL;
98
- apr_bucket_free(buf);
99
- return ret;
103
+ buf = (char *) apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, bucket->list);
104
+ if (buf == NULL) {
105
+ return APR_ENOMEM;
100
106
  }
101
- /*
102
- * If there's more to read we have to keep the rest of the pipe
103
- * for later.
104
- */
105
- if (*len > 0) {
107
+
108
+ do {
109
+ ret = read(data->stream, buf, APR_BUCKET_BUFF_SIZE);
110
+ } while (ret == -1 && errno == EINTR);
111
+
112
+ if (ret > 0) {
106
113
  apr_bucket_heap *h;
107
114
 
115
+ data->state->bytesRead += ret;
116
+
108
117
  *str = buf;
118
+ *len = ret;
109
119
  bucket->data = NULL;
110
120
 
111
- /* Change the current bucket to refer to what we read */
121
+ /* Change the current bucket (which is a Passenger Bucket) into a heap bucket
122
+ * that contains the data that we just read. This newly created heap bucket
123
+ * will be the first in the bucket list.
124
+ */
112
125
  bucket = apr_bucket_heap_make(bucket, buf, *len, apr_bucket_free);
113
126
  h = (apr_bucket_heap *) bucket->data;
114
127
  h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
128
+
129
+ /* And after this newly created bucket we insert a new Passenger Bucket
130
+ * which can read the next chunk from the stream.
131
+ */
115
132
  APR_BUCKET_INSERT_AFTER(bucket, passenger_bucket_create(
116
- data->session, pipe, bucket->list));
133
+ data->session, data->state, bucket->list));
134
+
135
+ /* The newly created Passenger Bucket has a reference to the session
136
+ * object, so we can delete data here.
137
+ */
117
138
  delete data;
118
- } else {
139
+
140
+ return APR_SUCCESS;
141
+
142
+ } else if (ret == 0) {
143
+ data->state->completed = true;
119
144
  delete data;
120
145
  bucket->data = NULL;
121
146
 
122
- apr_bucket_free(buf);
123
147
  bucket = apr_bucket_immortal_make(bucket, "", 0);
124
148
  *str = (const char *) bucket->data;
125
- // if (rv != APR_EOF) {
126
- // ... we might want to set an error flag here ...
127
- // }
149
+ *len = 0;
150
+ return APR_SUCCESS;
151
+
152
+ } else /* ret == -1 */ {
153
+ int e = errno;
154
+ data->state->completed = true;
155
+ data->state->errorCode = e;
156
+ delete data;
157
+ bucket->data = NULL;
158
+ apr_bucket_free(buf);
159
+ return APR_FROM_OS_ERROR(e);
128
160
  }
129
- return APR_SUCCESS;
130
161
  }
131
162
 
132
163
  static apr_bucket *
133
- passenger_bucket_make(apr_bucket *bucket, Application::SessionPtr session, apr_file_t *pipe) {
164
+ passenger_bucket_make(apr_bucket *bucket, Application::SessionPtr session, PassengerBucketStatePtr state) {
134
165
  BucketData *data = new BucketData();
135
166
  data->session = session;
136
- data->pipe = pipe;
167
+ data->stream = session->getStream();
168
+ data->state = state;
137
169
 
138
170
  bucket->type = &apr_bucket_type_passenger_pipe;
139
171
  bucket->length = (apr_size_t)(-1);
@@ -143,13 +175,14 @@ passenger_bucket_make(apr_bucket *bucket, Application::SessionPtr session, apr_f
143
175
  }
144
176
 
145
177
  apr_bucket *
146
- passenger_bucket_create(Application::SessionPtr session, apr_file_t *pipe, apr_bucket_alloc_t *list) {
178
+ passenger_bucket_create(Application::SessionPtr session, PassengerBucketStatePtr state, apr_bucket_alloc_t *list) {
147
179
  apr_bucket *bucket;
148
180
 
149
181
  bucket = (apr_bucket *) apr_bucket_alloc(sizeof(*bucket), list);
150
182
  APR_BUCKET_INIT(bucket);
151
183
  bucket->free = apr_bucket_free;
152
184
  bucket->list = list;
153
- return passenger_bucket_make(bucket, session, pipe);
185
+ return passenger_bucket_make(bucket, session, state);
154
186
  }
155
187
 
188
+ } // namespace Passenger
data/ext/apache2/Bucket.h CHANGED
@@ -25,26 +25,63 @@
25
25
  #ifndef _PASSENGER_BUCKET_H_
26
26
  #define _PASSENGER_BUCKET_H_
27
27
 
28
- /**
29
- * apr_bucket_pipe closes a pipe's file descriptor when it has reached
30
- * end-of-stream, but not when an error has occurred. This behavior is
31
- * undesirable because it can easily cause file descriptor leaks.
32
- *
33
- * passenger_bucket is like apr_bucket_pipe, but it also holds a reference to
34
- * a Session. When a read error has occured or when end-of-stream has been
35
- * reached, the Session will be dereferenced, so that the underlying file
36
- * descriptor is closed.
37
- *
38
- * passenger_bucket also ignores the APR_NONBLOCK_READ flag because that's
39
- * known to cause strange I/O problems.
40
- */
41
-
28
+ #include <boost/shared_ptr.hpp>
42
29
  #include <apr_buckets.h>
43
30
  #include "Application.h"
44
31
 
32
+ namespace Passenger {
33
+
34
+ using namespace boost;
35
+
36
+ struct PassengerBucketState {
37
+ /** The number of bytes that this PassengerBucket has read so far. */
38
+ unsigned long bytesRead;
39
+
40
+ /** Whether this PassengerBucket is completed, i.e. no more data
41
+ * can be read from the underlying file descriptor. When true,
42
+ * this can either mean that EOF has been reached, or that an I/O
43
+ * error occured. Use errorCode to check whether an error occurred.
44
+ */
45
+ bool completed;
46
+
47
+ /** When completed is true, errorCode contains the errno value of
48
+ * the last read() call.
49
+ *
50
+ * A value of 0 means that no error occured.
51
+ */
52
+ int errorCode;
53
+
54
+ PassengerBucketState() {
55
+ bytesRead = 0;
56
+ completed = false;
57
+ errorCode = 0;
58
+ }
59
+ };
60
+
61
+ typedef shared_ptr<PassengerBucketState> PassengerBucketStatePtr;
62
+
63
+ /**
64
+ * We used to use an apr_bucket_pipe for forwarding the backend process's
65
+ * response to the HTTP client. However, apr_bucket_pipe has a number of
66
+ * issues:
67
+ * - It closes the pipe's file descriptor when it has reached
68
+ * end-of-stream, but not when an error has occurred. This behavior is
69
+ * undesirable because it can easily cause file descriptor leaks.
70
+ * - It does weird non-blocking-I/O related things which can cause it
71
+ * to read less data than can actually be read.
72
+ *
73
+ * PassengerBucket is like apr_bucket_pipe, but:
74
+ * - It also holds a reference to a Session. When a read error has occured
75
+ * or when end-of-stream has been reached, the Session will be
76
+ * dereferenced, so that the underlying file descriptor is closed.
77
+ * - It ignores the APR_NONBLOCK_READ flag because that's known to cause
78
+ * strange I/O problems.
79
+ * - It can store its current state in a PassengerBucketState data structure.
80
+ */
45
81
  apr_bucket *passenger_bucket_create(Passenger::Application::SessionPtr session,
46
- apr_file_t *pipe,
82
+ PassengerBucketStatePtr state,
47
83
  apr_bucket_alloc_t *list);
48
84
 
49
- #endif /* _PASSENGER_BUCKET_H_ */
85
+ } // namespace Passenger
50
86
 
87
+ #endif /* _PASSENGER_BUCKET_H_ */