passenger 5.0.4 → 5.0.5

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 (550) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.editorconfig +10 -0
  5. data/CHANGELOG +21 -0
  6. data/build/agents.rb +2 -2
  7. data/build/apache2.rb +6 -5
  8. data/build/common_library.rb +22 -7
  9. data/build/cxx_tests.rb +0 -3
  10. data/build/misc.rb +1 -1
  11. data/dev/parse_file_descriptor_log +119 -0
  12. data/doc/CloudLicensingConfiguration.html +387 -0
  13. data/doc/Design and Architecture.html +2430 -0
  14. data/doc/Packaging.html +488 -0
  15. data/doc/Security of user switching support.html +1833 -0
  16. data/doc/ServerOptimizationGuide.html +659 -0
  17. data/doc/ServerOptimizationGuide.txt.md +8 -0
  18. data/doc/Users guide Apache.html +9116 -0
  19. data/doc/Users guide Apache.idmap.txt +6 -2
  20. data/doc/Users guide Apache.txt +26 -7
  21. data/doc/Users guide Nginx.html +9025 -0
  22. data/doc/Users guide Nginx.idmap.txt +7 -3
  23. data/doc/Users guide Nginx.txt +29 -6
  24. data/doc/Users guide Standalone.html +3983 -0
  25. data/doc/Users guide.html +1748 -0
  26. data/doc/users_guide_snippets/installation.txt +4 -4
  27. data/ext/apache2/Configuration.cpp +16 -5
  28. data/ext/apache2/Configuration.hpp +4 -2
  29. data/ext/apache2/Hooks.cpp +44 -19
  30. data/ext/boost/libs/thread/src/pthread/once.cpp +2 -0
  31. data/ext/boost/libs/thread/src/pthread/once_atomic.cpp +6 -0
  32. data/ext/common/AgentsStarter.h +3 -2
  33. data/ext/common/ApplicationPool2/DirectSpawner.h +14 -4
  34. data/ext/common/ApplicationPool2/DummySpawner.h +12 -7
  35. data/ext/common/ApplicationPool2/Implementation.cpp +1 -1
  36. data/ext/common/ApplicationPool2/Process.h +2 -1
  37. data/ext/common/ApplicationPool2/Session.h +6 -6
  38. data/ext/common/ApplicationPool2/SmartSpawner.h +19 -4
  39. data/ext/common/ApplicationPool2/Socket.h +59 -27
  40. data/ext/common/ApplicationPool2/Spawner.h +2 -2
  41. data/ext/common/BackgroundEventLoop.cpp +6 -1
  42. data/ext/common/Constants.h +1 -1
  43. data/ext/common/EventedClient.h +1 -1
  44. data/ext/common/EventedServer.h +2 -2
  45. data/ext/common/FileDescriptor.h +25 -6
  46. data/ext/common/Logging.cpp +107 -52
  47. data/ext/common/Logging.h +146 -19
  48. data/ext/common/MessageClient.h +2 -2
  49. data/ext/common/MessageServer.h +3 -2
  50. data/ext/common/RandomGenerator.h +8 -7
  51. data/ext/common/SafeLibev.h +5 -1
  52. data/ext/common/ServerKit/AcceptLoadBalancer.h +9 -4
  53. data/ext/common/ServerKit/FdSinkChannel.h +5 -2
  54. data/ext/common/ServerKit/FdSourceChannel.h +5 -2
  55. data/ext/common/ServerKit/FileBufferedChannel.h +2 -0
  56. data/ext/common/ServerKit/FileBufferedFdSinkChannel.h +7 -2
  57. data/ext/common/ServerKit/HttpServer.h +6 -0
  58. data/ext/common/ServerKit/Server.h +40 -3
  59. data/ext/common/StaticString.h +20 -0
  60. data/ext/common/UnionStation/Connection.h +3 -1
  61. data/ext/common/UnionStation/Core.h +6 -4
  62. data/ext/common/Utils.cpp +4 -3
  63. data/ext/common/Utils/DateParsing.h +19 -5
  64. data/ext/common/Utils/FastStringStream.h +183 -0
  65. data/ext/common/Utils/IOUtils.cpp +47 -28
  66. data/ext/common/Utils/IOUtils.h +56 -12
  67. data/ext/common/Utils/MessagePassing.h +3 -3
  68. data/ext/common/Utils/ProcessMetricsCollector.h +2 -2
  69. data/ext/common/Utils/ScopeGuard.h +16 -5
  70. data/ext/common/Utils/SpeedMeter.h +2 -2
  71. data/ext/common/Utils/StrIntUtils.cpp +6 -6
  72. data/ext/common/Utils/StrIntUtils.h +2 -1
  73. data/ext/common/agents/Base.cpp +56 -4
  74. data/ext/common/agents/Base.h +2 -1
  75. data/ext/common/agents/HelperAgent/AdminServer.h +122 -11
  76. data/ext/common/agents/HelperAgent/Main.cpp +16 -5
  77. data/ext/common/agents/HelperAgent/OptionParser.h +7 -1
  78. data/ext/common/agents/HelperAgent/RequestHandler.h +1 -1
  79. data/ext/common/agents/HelperAgent/RequestHandler/Hooks.cpp +10 -1
  80. data/ext/common/agents/HelperAgent/RequestHandler/Request.h +8 -0
  81. data/ext/common/agents/HelperAgent/RequestHandler/TurboCaching.h +4 -3
  82. data/ext/common/agents/LoggingAgent/AdminServer.h +57 -11
  83. data/ext/common/agents/LoggingAgent/LoggingServer.h +3 -3
  84. data/ext/common/agents/LoggingAgent/Main.cpp +11 -3
  85. data/ext/common/agents/Watchdog/AdminServer.h +53 -11
  86. data/ext/common/agents/Watchdog/AgentWatcher.cpp +3 -3
  87. data/ext/common/agents/Watchdog/Main.cpp +13 -6
  88. data/ext/libeio/ecb.h +1 -1
  89. data/ext/libev/ev.c +13 -1
  90. data/ext/libev/ev.h +3 -0
  91. data/ext/nginx/Configuration.c +28 -6
  92. data/ext/nginx/Configuration.h +2 -1
  93. data/ext/nginx/ngx_http_passenger_module.c +5 -4
  94. data/ext/oxt/dynamic_thread_group.hpp +38 -5
  95. data/lib/phusion_passenger.rb +1 -1
  96. data/lib/phusion_passenger/common_library.rb +9 -5
  97. data/lib/phusion_passenger/config/reopen_logs_command.rb +2 -2
  98. data/lib/phusion_passenger/packaging.rb +23 -37
  99. data/passenger.gemspec +21 -21
  100. metadata +4 -453
  101. metadata.gz.asc +7 -7
  102. data/.gitignore +0 -68
  103. data/.travis.yml +0 -16
  104. data/Gemfile +0 -17
  105. data/Gemfile.lock +0 -39
  106. data/Vagrantfile +0 -54
  107. data/debian.template/README.Debian +0 -15
  108. data/debian.template/changelog +0 -316
  109. data/debian.template/compat +0 -1
  110. data/debian.template/control.erb +0 -91
  111. data/debian.template/copyright +0 -385
  112. data/debian.template/libapache2-mod-passenger.install +0 -3
  113. data/debian.template/libapache2-mod-passenger.postinst +0 -36
  114. data/debian.template/libapache2-mod-passenger.prerm +0 -15
  115. data/debian.template/locations.ini.erb +0 -14
  116. data/debian.template/passenger-dev.install.erb +0 -3
  117. data/debian.template/passenger-doc.install.erb +0 -2
  118. data/debian.template/passenger.conf +0 -6
  119. data/debian.template/passenger.docs +0 -4
  120. data/debian.template/passenger.install.erb +0 -14
  121. data/debian.template/passenger.load +0 -3
  122. data/debian.template/passenger.manpages +0 -3
  123. data/debian.template/patches/series +0 -0
  124. data/debian.template/rules.erb +0 -76
  125. data/debian.template/source/format +0 -1
  126. data/ext/common/EventedBufferedInput.h +0 -458
  127. data/packaging/rpm/LICENSE.txt +0 -19
  128. data/packaging/rpm/Makefile +0 -13
  129. data/packaging/rpm/README.md +0 -41
  130. data/packaging/rpm/Vagrantfile +0 -38
  131. data/packaging/rpm/Vagrantfile.centos +0 -30
  132. data/packaging/rpm/build +0 -170
  133. data/packaging/rpm/create_project +0 -41
  134. data/packaging/rpm/git_update +0 -88
  135. data/packaging/rpm/image/Dockerfile +0 -37
  136. data/packaging/rpm/image/Gemfile +0 -3
  137. data/packaging/rpm/image/Gemfile.lock +0 -12
  138. data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +0 -19
  139. data/packaging/rpm/image/amazon2014-i386.cfg +0 -96
  140. data/packaging/rpm/image/amazon2014-x86_64.cfg +0 -96
  141. data/packaging/rpm/image/site-defaults.cfg +0 -168
  142. data/packaging/rpm/internal/build_tasks.rb +0 -238
  143. data/packaging/rpm/internal/dummygpg +0 -11
  144. data/packaging/rpm/internal/exec_build +0 -42
  145. data/packaging/rpm/internal/get_distro_arch +0 -14
  146. data/packaging/rpm/internal/get_distro_id +0 -10
  147. data/packaging/rpm/internal/git_update +0 -27
  148. data/packaging/rpm/internal/inituidgid +0 -17
  149. data/packaging/rpm/internal/my_init +0 -344
  150. data/packaging/rpm/internal/python27 +0 -3
  151. data/packaging/rpm/internal/repo_update +0 -46
  152. data/packaging/rpm/internal/setuser +0 -26
  153. data/packaging/rpm/internal/tracking_helper +0 -40
  154. data/packaging/rpm/jenkins_release +0 -99
  155. data/packaging/rpm/lib/build_tasks_support.rb +0 -402
  156. data/packaging/rpm/lib/preprocessor.rb +0 -341
  157. data/packaging/rpm/nginx_spec/404.html +0 -119
  158. data/packaging/rpm/nginx_spec/50x.html +0 -119
  159. data/packaging/rpm/nginx_spec/index.html +0 -116
  160. data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +0 -13
  161. data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
  162. data/packaging/rpm/nginx_spec/nginx-upgrade +0 -13
  163. data/packaging/rpm/nginx_spec/nginx-upgrade.8 +0 -151
  164. data/packaging/rpm/nginx_spec/nginx.conf +0 -131
  165. data/packaging/rpm/nginx_spec/nginx.init +0 -144
  166. data/packaging/rpm/nginx_spec/nginx.logrotate +0 -13
  167. data/packaging/rpm/nginx_spec/nginx.service +0 -15
  168. data/packaging/rpm/nginx_spec/nginx.spec.template +0 -560
  169. data/packaging/rpm/nginx_spec/nginx.sysconfig +0 -4
  170. data/packaging/rpm/nginx_spec/passenger.conf +0 -9
  171. data/packaging/rpm/nginx_spec/poweredby.png +0 -0
  172. data/packaging/rpm/passenger_spec/apache-passenger.conf.in +0 -26
  173. data/packaging/rpm/passenger_spec/config.json +0 -30
  174. data/packaging/rpm/passenger_spec/passenger.logrotate +0 -7
  175. data/packaging/rpm/passenger_spec/passenger.spec.template +0 -478
  176. data/packaging/rpm/passenger_spec/passenger_dynamic_thread_group.patch +0 -16
  177. data/packaging/rpm/passenger_spec/passenger_tests_default_config_example.patch +0 -44
  178. data/packaging/rpm/passenger_spec/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -21
  179. data/packaging/rpm/repo_update +0 -114
  180. data/packaging/rpm/setup-system +0 -61
  181. data/packaging/rpm/shell +0 -10
  182. data/test/.rspec +0 -4
  183. data/test/config.json.example +0 -42
  184. data/test/config.json.rpm-automation +0 -15
  185. data/test/config.json.travis +0 -15
  186. data/test/config.json.vagrant +0 -30
  187. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +0 -124
  188. data/test/cxx/ApplicationPool2/OptionsTest.cpp +0 -30
  189. data/test/cxx/ApplicationPool2/PoolTest.cpp +0 -2062
  190. data/test/cxx/ApplicationPool2/ProcessTest.cpp +0 -130
  191. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +0 -243
  192. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +0 -823
  193. data/test/cxx/BufferedIOTest.cpp +0 -364
  194. data/test/cxx/CachedFileStatTest.cpp +0 -402
  195. data/test/cxx/CxxTestMain.cpp +0 -181
  196. data/test/cxx/DataStructures/LStringTest.cpp +0 -275
  197. data/test/cxx/DataStructures/StringKeyTableTest.cpp +0 -199
  198. data/test/cxx/DateParsingTest.cpp +0 -75
  199. data/test/cxx/DechunkerTest.cpp +0 -250
  200. data/test/cxx/EventedBufferedInputTest.cpp +0 -758
  201. data/test/cxx/EventedClientTest.cpp +0 -523
  202. data/test/cxx/FileChangeCheckerTest.cpp +0 -331
  203. data/test/cxx/FileDescriptorTest.cpp +0 -69
  204. data/test/cxx/FilterSupportTest.cpp +0 -433
  205. data/test/cxx/IOUtilsTest.cpp +0 -861
  206. data/test/cxx/MemoryKit/MbufTest.cpp +0 -213
  207. data/test/cxx/MessageIOTest.cpp +0 -360
  208. data/test/cxx/MessagePassingTest.cpp +0 -81
  209. data/test/cxx/MessageReadersWritersTest.cpp +0 -576
  210. data/test/cxx/MessageServerTest.cpp +0 -393
  211. data/test/cxx/ProcessMetricsCollectorTest.cpp +0 -123
  212. data/test/cxx/RequestHandlerTest.cpp +0 -1463
  213. data/test/cxx/ResponseCacheTest.cpp +0 -322
  214. data/test/cxx/ServerKit/ChannelTest.cpp +0 -1467
  215. data/test/cxx/ServerKit/CookieUtilsTest.cpp +0 -274
  216. data/test/cxx/ServerKit/FileBufferedChannelTest.cpp +0 -992
  217. data/test/cxx/ServerKit/HeaderTableTest.cpp +0 -177
  218. data/test/cxx/ServerKit/HttpServerTest.cpp +0 -1580
  219. data/test/cxx/ServerKit/ServerTest.cpp +0 -408
  220. data/test/cxx/StaticStringTest.cpp +0 -220
  221. data/test/cxx/StringMapTest.cpp +0 -131
  222. data/test/cxx/SystemTimeTest.cpp +0 -37
  223. data/test/cxx/TemplateTest.cpp +0 -118
  224. data/test/cxx/TestSupport.cpp +0 -207
  225. data/test/cxx/TestSupport.h +0 -333
  226. data/test/cxx/UnionStationTest.cpp +0 -741
  227. data/test/cxx/Utils/StrIntUtilsTest.cpp +0 -39
  228. data/test/cxx/UtilsTest.cpp +0 -672
  229. data/test/cxx/VariantMapTest.cpp +0 -191
  230. data/test/gdbinit.example +0 -34
  231. data/test/integration_tests/apache2_tests.rb +0 -585
  232. data/test/integration_tests/downloaded_binaries_tests.rb +0 -185
  233. data/test/integration_tests/native_packaging_spec.rb +0 -368
  234. data/test/integration_tests/nginx_tests.rb +0 -402
  235. data/test/integration_tests/shared/example_webapp_tests.rb +0 -289
  236. data/test/integration_tests/source_packaging_test.rb +0 -201
  237. data/test/integration_tests/spec_helper.rb +0 -22
  238. data/test/integration_tests/standalone_tests.rb +0 -392
  239. data/test/node/line_reader_spec.js +0 -338
  240. data/test/node/spec_helper.js +0 -65
  241. data/test/oxt/backtrace_test.cpp +0 -88
  242. data/test/oxt/counter.hpp +0 -55
  243. data/test/oxt/dynamic_thread_group_test.cpp +0 -131
  244. data/test/oxt/oxt_test_main.cpp +0 -27
  245. data/test/oxt/spin_lock_test.cpp +0 -59
  246. data/test/oxt/syscall_interruption_test.cpp +0 -39
  247. data/test/ruby/debug_logging_spec.rb +0 -145
  248. data/test/ruby/message_channel_spec.rb +0 -196
  249. data/test/ruby/rack/loader_spec.rb +0 -42
  250. data/test/ruby/rack/preloader_spec.rb +0 -48
  251. data/test/ruby/rails3.0/loader_spec.rb +0 -26
  252. data/test/ruby/rails3.0/preloader_spec.rb +0 -32
  253. data/test/ruby/rails3.1/loader_spec.rb +0 -26
  254. data/test/ruby/rails3.1/preloader_spec.rb +0 -32
  255. data/test/ruby/rails3.2/loader_spec.rb +0 -26
  256. data/test/ruby/rails3.2/preloader_spec.rb +0 -32
  257. data/test/ruby/rails4.0/loader_spec.rb +0 -28
  258. data/test/ruby/rails4.0/preloader_spec.rb +0 -34
  259. data/test/ruby/rails4.1/loader_spec.rb +0 -28
  260. data/test/ruby/rails4.1/preloader_spec.rb +0 -34
  261. data/test/ruby/request_handler_spec.rb +0 -747
  262. data/test/ruby/shared/loader_sharedspec.rb +0 -247
  263. data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +0 -357
  264. data/test/ruby/shared/ruby_loader_sharedspec.rb +0 -55
  265. data/test/ruby/spec_helper.rb +0 -114
  266. data/test/ruby/standalone/runtime_installer_spec.rb +0 -402
  267. data/test/ruby/union_station_spec.rb +0 -288
  268. data/test/ruby/utils/file_system_watcher_spec.rb +0 -229
  269. data/test/ruby/utils/hosts_file_parser.rb +0 -258
  270. data/test/ruby/utils/tee_input_spec.rb +0 -235
  271. data/test/ruby/utils/unseekable_socket_spec.rb +0 -66
  272. data/test/ruby/utils_spec.rb +0 -41
  273. data/test/stub/apache2/httpd.conf.erb +0 -122
  274. data/test/stub/apache2/mime.types +0 -748
  275. data/test/stub/garbage1.dat +0 -0
  276. data/test/stub/garbage2.dat +0 -0
  277. data/test/stub/garbage3.dat +0 -0
  278. data/test/stub/http_request.yml +0 -23
  279. data/test/stub/index.html +0 -1
  280. data/test/stub/nginx/koi-utf +0 -109
  281. data/test/stub/nginx/koi-win +0 -103
  282. data/test/stub/nginx/mime.types +0 -70
  283. data/test/stub/nginx/nginx.conf.erb +0 -70
  284. data/test/stub/nginx/win-utf +0 -126
  285. data/test/stub/node/app.js +0 -133
  286. data/test/stub/node/public/.gitignore +0 -0
  287. data/test/stub/node/tmp/.gitignore +0 -0
  288. data/test/stub/rack/config.ru +0 -95
  289. data/test/stub/rack/library.rb +0 -16
  290. data/test/stub/rack/public/.gitignore +0 -0
  291. data/test/stub/rack/start.rb +0 -52
  292. data/test/stub/rack/tmp/.gitignore +0 -0
  293. data/test/stub/rails3.0/.gitignore +0 -4
  294. data/test/stub/rails3.0/Gemfile +0 -22
  295. data/test/stub/rails3.0/Gemfile.lock +0 -80
  296. data/test/stub/rails3.0/Rakefile +0 -10
  297. data/test/stub/rails3.0/app/controllers/application_controller.rb +0 -4
  298. data/test/stub/rails3.0/app/helpers/application_helper.rb +0 -2
  299. data/test/stub/rails3.0/app/views/layouts/application.html.erb +0 -14
  300. data/test/stub/rails3.0/config.ru +0 -4
  301. data/test/stub/rails3.0/config/application.rb +0 -48
  302. data/test/stub/rails3.0/config/boot.rb +0 -13
  303. data/test/stub/rails3.0/config/database.yml +0 -22
  304. data/test/stub/rails3.0/config/environment.rb +0 -5
  305. data/test/stub/rails3.0/config/environments/development.rb +0 -19
  306. data/test/stub/rails3.0/config/environments/production.rb +0 -48
  307. data/test/stub/rails3.0/config/environments/test.rb +0 -32
  308. data/test/stub/rails3.0/config/initializers/backtrace_silencers.rb +0 -7
  309. data/test/stub/rails3.0/config/initializers/inflections.rb +0 -10
  310. data/test/stub/rails3.0/config/initializers/mime_types.rb +0 -5
  311. data/test/stub/rails3.0/config/initializers/passenger.rb +0 -2
  312. data/test/stub/rails3.0/config/initializers/secret_token.rb +0 -7
  313. data/test/stub/rails3.0/config/initializers/session_store.rb +0 -8
  314. data/test/stub/rails3.0/config/locales/en.yml +0 -5
  315. data/test/stub/rails3.0/config/routes.rb +0 -58
  316. data/test/stub/rails3.0/db/seeds.rb +0 -7
  317. data/test/stub/rails3.0/doc/README_FOR_APP +0 -2
  318. data/test/stub/rails3.0/lib/tasks/.gitkeep +0 -0
  319. data/test/stub/rails3.0/log/.gitignore +0 -0
  320. data/test/stub/rails3.0/public/404.html +0 -26
  321. data/test/stub/rails3.0/public/422.html +0 -26
  322. data/test/stub/rails3.0/public/500.html +0 -26
  323. data/test/stub/rails3.0/public/favicon.ico +0 -0
  324. data/test/stub/rails3.0/public/index.html +0 -279
  325. data/test/stub/rails3.0/public/robots.txt +0 -5
  326. data/test/stub/rails3.0/public/stylesheets/.gitkeep +0 -0
  327. data/test/stub/rails3.0/script/rails +0 -9
  328. data/test/stub/rails3.0/test/performance/browsing_test.rb +0 -9
  329. data/test/stub/rails3.0/test/test_helper.rb +0 -13
  330. data/test/stub/rails3.0/vendor/plugins/.gitkeep +0 -0
  331. data/test/stub/rails3.1/.gitignore +0 -15
  332. data/test/stub/rails3.1/Gemfile +0 -37
  333. data/test/stub/rails3.1/Gemfile.lock +0 -115
  334. data/test/stub/rails3.1/README +0 -261
  335. data/test/stub/rails3.1/Rakefile +0 -7
  336. data/test/stub/rails3.1/app/assets/images/rails.png +0 -0
  337. data/test/stub/rails3.1/app/assets/stylesheets/application.css +0 -7
  338. data/test/stub/rails3.1/app/controllers/application_controller.rb +0 -3
  339. data/test/stub/rails3.1/app/helpers/application_helper.rb +0 -2
  340. data/test/stub/rails3.1/app/mailers/.gitkeep +0 -0
  341. data/test/stub/rails3.1/app/models/.gitkeep +0 -0
  342. data/test/stub/rails3.1/app/views/layouts/application.html.erb +0 -14
  343. data/test/stub/rails3.1/config.ru +0 -4
  344. data/test/stub/rails3.1/config/application.rb +0 -48
  345. data/test/stub/rails3.1/config/boot.rb +0 -6
  346. data/test/stub/rails3.1/config/database.yml +0 -25
  347. data/test/stub/rails3.1/config/environment.rb +0 -5
  348. data/test/stub/rails3.1/config/environments/development.rb +0 -30
  349. data/test/stub/rails3.1/config/environments/production.rb +0 -60
  350. data/test/stub/rails3.1/config/environments/test.rb +0 -39
  351. data/test/stub/rails3.1/config/initializers/backtrace_silencers.rb +0 -7
  352. data/test/stub/rails3.1/config/initializers/inflections.rb +0 -10
  353. data/test/stub/rails3.1/config/initializers/mime_types.rb +0 -5
  354. data/test/stub/rails3.1/config/initializers/passenger.rb +0 -2
  355. data/test/stub/rails3.1/config/initializers/secret_token.rb +0 -7
  356. data/test/stub/rails3.1/config/initializers/session_store.rb +0 -8
  357. data/test/stub/rails3.1/config/initializers/wrap_parameters.rb +0 -14
  358. data/test/stub/rails3.1/config/locales/en.yml +0 -5
  359. data/test/stub/rails3.1/config/routes.rb +0 -58
  360. data/test/stub/rails3.1/db/seeds.rb +0 -7
  361. data/test/stub/rails3.1/doc/README_FOR_APP +0 -2
  362. data/test/stub/rails3.1/lib/assets/.gitkeep +0 -0
  363. data/test/stub/rails3.1/lib/tasks/.gitkeep +0 -0
  364. data/test/stub/rails3.1/log/.gitkeep +0 -0
  365. data/test/stub/rails3.1/public/404.html +0 -26
  366. data/test/stub/rails3.1/public/422.html +0 -26
  367. data/test/stub/rails3.1/public/500.html +0 -26
  368. data/test/stub/rails3.1/public/favicon.ico +0 -0
  369. data/test/stub/rails3.1/public/index.html +0 -241
  370. data/test/stub/rails3.1/public/robots.txt +0 -5
  371. data/test/stub/rails3.1/script/rails +0 -6
  372. data/test/stub/rails3.1/test/fixtures/.gitkeep +0 -0
  373. data/test/stub/rails3.1/test/functional/.gitkeep +0 -0
  374. data/test/stub/rails3.1/test/integration/.gitkeep +0 -0
  375. data/test/stub/rails3.1/test/performance/browsing_test.rb +0 -12
  376. data/test/stub/rails3.1/test/test_helper.rb +0 -13
  377. data/test/stub/rails3.1/test/unit/.gitkeep +0 -0
  378. data/test/stub/rails3.1/vendor/assets/stylesheets/.gitkeep +0 -0
  379. data/test/stub/rails3.1/vendor/plugins/.gitkeep +0 -0
  380. data/test/stub/rails3.2/.gitignore +0 -15
  381. data/test/stub/rails3.2/Gemfile +0 -39
  382. data/test/stub/rails3.2/Gemfile.lock +0 -113
  383. data/test/stub/rails3.2/Rakefile +0 -7
  384. data/test/stub/rails3.2/app/assets/images/rails.png +0 -0
  385. data/test/stub/rails3.2/app/assets/stylesheets/application.css +0 -13
  386. data/test/stub/rails3.2/app/controllers/application_controller.rb +0 -3
  387. data/test/stub/rails3.2/app/helpers/application_helper.rb +0 -2
  388. data/test/stub/rails3.2/app/mailers/.gitkeep +0 -0
  389. data/test/stub/rails3.2/app/models/.gitkeep +0 -0
  390. data/test/stub/rails3.2/app/views/layouts/application.html.erb +0 -14
  391. data/test/stub/rails3.2/config.ru +0 -4
  392. data/test/stub/rails3.2/config/application.rb +0 -62
  393. data/test/stub/rails3.2/config/boot.rb +0 -6
  394. data/test/stub/rails3.2/config/database.yml +0 -25
  395. data/test/stub/rails3.2/config/environment.rb +0 -5
  396. data/test/stub/rails3.2/config/environments/development.rb +0 -37
  397. data/test/stub/rails3.2/config/environments/production.rb +0 -67
  398. data/test/stub/rails3.2/config/environments/test.rb +0 -37
  399. data/test/stub/rails3.2/config/initializers/backtrace_silencers.rb +0 -7
  400. data/test/stub/rails3.2/config/initializers/inflections.rb +0 -15
  401. data/test/stub/rails3.2/config/initializers/mime_types.rb +0 -5
  402. data/test/stub/rails3.2/config/initializers/passenger.rb +0 -2
  403. data/test/stub/rails3.2/config/initializers/secret_token.rb +0 -7
  404. data/test/stub/rails3.2/config/initializers/session_store.rb +0 -8
  405. data/test/stub/rails3.2/config/initializers/wrap_parameters.rb +0 -14
  406. data/test/stub/rails3.2/config/locales/en.yml +0 -5
  407. data/test/stub/rails3.2/config/routes.rb +0 -58
  408. data/test/stub/rails3.2/db/seeds.rb +0 -7
  409. data/test/stub/rails3.2/doc/README_FOR_APP +0 -2
  410. data/test/stub/rails3.2/lib/assets/.gitkeep +0 -0
  411. data/test/stub/rails3.2/lib/tasks/.gitkeep +0 -0
  412. data/test/stub/rails3.2/log/.gitkeep +0 -0
  413. data/test/stub/rails3.2/public/404.html +0 -26
  414. data/test/stub/rails3.2/public/422.html +0 -26
  415. data/test/stub/rails3.2/public/500.html +0 -25
  416. data/test/stub/rails3.2/public/favicon.ico +0 -0
  417. data/test/stub/rails3.2/public/index.html +0 -241
  418. data/test/stub/rails3.2/public/robots.txt +0 -5
  419. data/test/stub/rails3.2/script/rails +0 -6
  420. data/test/stub/rails3.2/test/fixtures/.gitkeep +0 -0
  421. data/test/stub/rails3.2/test/functional/.gitkeep +0 -0
  422. data/test/stub/rails3.2/test/integration/.gitkeep +0 -0
  423. data/test/stub/rails3.2/test/performance/browsing_test.rb +0 -12
  424. data/test/stub/rails3.2/test/test_helper.rb +0 -13
  425. data/test/stub/rails3.2/test/unit/.gitkeep +0 -0
  426. data/test/stub/rails3.2/vendor/assets/stylesheets/.gitkeep +0 -0
  427. data/test/stub/rails3.2/vendor/plugins/.gitkeep +0 -0
  428. data/test/stub/rails4.0/.gitignore +0 -16
  429. data/test/stub/rails4.0/Gemfile +0 -45
  430. data/test/stub/rails4.0/Gemfile.lock +0 -126
  431. data/test/stub/rails4.0/README.rdoc +0 -28
  432. data/test/stub/rails4.0/Rakefile +0 -6
  433. data/test/stub/rails4.0/app/assets/images/.keep +0 -0
  434. data/test/stub/rails4.0/app/assets/javascripts/application.js +0 -16
  435. data/test/stub/rails4.0/app/assets/stylesheets/application.css +0 -13
  436. data/test/stub/rails4.0/app/controllers/application_controller.rb +0 -5
  437. data/test/stub/rails4.0/app/controllers/concerns/.keep +0 -0
  438. data/test/stub/rails4.0/app/helpers/application_helper.rb +0 -2
  439. data/test/stub/rails4.0/app/mailers/.keep +0 -0
  440. data/test/stub/rails4.0/app/models/.keep +0 -0
  441. data/test/stub/rails4.0/app/models/concerns/.keep +0 -0
  442. data/test/stub/rails4.0/app/views/layouts/application.html.erb +0 -14
  443. data/test/stub/rails4.0/bin/bundle +0 -3
  444. data/test/stub/rails4.0/bin/rails +0 -4
  445. data/test/stub/rails4.0/bin/rake +0 -4
  446. data/test/stub/rails4.0/config.ru +0 -4
  447. data/test/stub/rails4.0/config/application.rb +0 -23
  448. data/test/stub/rails4.0/config/boot.rb +0 -4
  449. data/test/stub/rails4.0/config/database.yml +0 -25
  450. data/test/stub/rails4.0/config/environment.rb +0 -5
  451. data/test/stub/rails4.0/config/environments/development.rb +0 -29
  452. data/test/stub/rails4.0/config/environments/production.rb +0 -80
  453. data/test/stub/rails4.0/config/environments/test.rb +0 -36
  454. data/test/stub/rails4.0/config/initializers/backtrace_silencers.rb +0 -7
  455. data/test/stub/rails4.0/config/initializers/filter_parameter_logging.rb +0 -4
  456. data/test/stub/rails4.0/config/initializers/inflections.rb +0 -16
  457. data/test/stub/rails4.0/config/initializers/mime_types.rb +0 -5
  458. data/test/stub/rails4.0/config/initializers/passenger.rb +0 -2
  459. data/test/stub/rails4.0/config/initializers/secret_token.rb +0 -12
  460. data/test/stub/rails4.0/config/initializers/session_store.rb +0 -3
  461. data/test/stub/rails4.0/config/initializers/wrap_parameters.rb +0 -14
  462. data/test/stub/rails4.0/config/locales/en.yml +0 -23
  463. data/test/stub/rails4.0/config/routes.rb +0 -57
  464. data/test/stub/rails4.0/db/seeds.rb +0 -7
  465. data/test/stub/rails4.0/lib/assets/.keep +0 -0
  466. data/test/stub/rails4.0/lib/tasks/.keep +0 -0
  467. data/test/stub/rails4.0/log/.keep +0 -0
  468. data/test/stub/rails4.0/public/404.html +0 -58
  469. data/test/stub/rails4.0/public/422.html +0 -58
  470. data/test/stub/rails4.0/public/500.html +0 -57
  471. data/test/stub/rails4.0/public/favicon.ico +0 -0
  472. data/test/stub/rails4.0/public/robots.txt +0 -5
  473. data/test/stub/rails4.0/test/controllers/.keep +0 -0
  474. data/test/stub/rails4.0/test/fixtures/.keep +0 -0
  475. data/test/stub/rails4.0/test/helpers/.keep +0 -0
  476. data/test/stub/rails4.0/test/integration/.keep +0 -0
  477. data/test/stub/rails4.0/test/mailers/.keep +0 -0
  478. data/test/stub/rails4.0/test/models/.keep +0 -0
  479. data/test/stub/rails4.0/test/test_helper.rb +0 -15
  480. data/test/stub/rails4.0/vendor/assets/javascripts/.keep +0 -0
  481. data/test/stub/rails4.0/vendor/assets/stylesheets/.keep +0 -0
  482. data/test/stub/rails4.1/.gitignore +0 -16
  483. data/test/stub/rails4.1/Gemfile +0 -45
  484. data/test/stub/rails4.1/Gemfile.lock +0 -129
  485. data/test/stub/rails4.1/README.rdoc +0 -28
  486. data/test/stub/rails4.1/Rakefile +0 -6
  487. data/test/stub/rails4.1/app/assets/images/.keep +0 -0
  488. data/test/stub/rails4.1/app/assets/javascripts/application.js +0 -16
  489. data/test/stub/rails4.1/app/assets/stylesheets/application.css +0 -13
  490. data/test/stub/rails4.1/app/controllers/application_controller.rb +0 -5
  491. data/test/stub/rails4.1/app/controllers/concerns/.keep +0 -0
  492. data/test/stub/rails4.1/app/helpers/application_helper.rb +0 -2
  493. data/test/stub/rails4.1/app/mailers/.keep +0 -0
  494. data/test/stub/rails4.1/app/models/.keep +0 -0
  495. data/test/stub/rails4.1/app/models/concerns/.keep +0 -0
  496. data/test/stub/rails4.1/app/views/layouts/application.html.erb +0 -14
  497. data/test/stub/rails4.1/bin/bundle +0 -3
  498. data/test/stub/rails4.1/bin/rails +0 -4
  499. data/test/stub/rails4.1/bin/rake +0 -4
  500. data/test/stub/rails4.1/config.ru +0 -4
  501. data/test/stub/rails4.1/config/application.rb +0 -23
  502. data/test/stub/rails4.1/config/boot.rb +0 -4
  503. data/test/stub/rails4.1/config/database.yml +0 -25
  504. data/test/stub/rails4.1/config/environment.rb +0 -5
  505. data/test/stub/rails4.1/config/environments/development.rb +0 -29
  506. data/test/stub/rails4.1/config/environments/production.rb +0 -80
  507. data/test/stub/rails4.1/config/environments/test.rb +0 -36
  508. data/test/stub/rails4.1/config/initializers/backtrace_silencers.rb +0 -7
  509. data/test/stub/rails4.1/config/initializers/filter_parameter_logging.rb +0 -4
  510. data/test/stub/rails4.1/config/initializers/inflections.rb +0 -16
  511. data/test/stub/rails4.1/config/initializers/mime_types.rb +0 -5
  512. data/test/stub/rails4.1/config/initializers/passenger.rb +0 -5
  513. data/test/stub/rails4.1/config/initializers/secret_token.rb +0 -12
  514. data/test/stub/rails4.1/config/initializers/session_store.rb +0 -3
  515. data/test/stub/rails4.1/config/initializers/wrap_parameters.rb +0 -14
  516. data/test/stub/rails4.1/config/locales/en.yml +0 -23
  517. data/test/stub/rails4.1/config/routes.rb +0 -57
  518. data/test/stub/rails4.1/db/seeds.rb +0 -7
  519. data/test/stub/rails4.1/lib/assets/.keep +0 -0
  520. data/test/stub/rails4.1/lib/tasks/.keep +0 -0
  521. data/test/stub/rails4.1/log/.keep +0 -0
  522. data/test/stub/rails4.1/public/404.html +0 -58
  523. data/test/stub/rails4.1/public/422.html +0 -58
  524. data/test/stub/rails4.1/public/500.html +0 -57
  525. data/test/stub/rails4.1/public/favicon.ico +0 -0
  526. data/test/stub/rails4.1/public/robots.txt +0 -5
  527. data/test/stub/rails4.1/test/controllers/.keep +0 -0
  528. data/test/stub/rails4.1/test/fixtures/.keep +0 -0
  529. data/test/stub/rails4.1/test/helpers/.keep +0 -0
  530. data/test/stub/rails4.1/test/integration/.keep +0 -0
  531. data/test/stub/rails4.1/test/mailers/.keep +0 -0
  532. data/test/stub/rails4.1/test/models/.keep +0 -0
  533. data/test/stub/rails4.1/test/test_helper.rb +0 -15
  534. data/test/stub/rails4.1/vendor/assets/javascripts/.keep +0 -0
  535. data/test/stub/rails4.1/vendor/assets/stylesheets/.keep +0 -0
  536. data/test/stub/start_error.pl +0 -24
  537. data/test/stub/upload_data.txt +0 -494
  538. data/test/stub/wsgi/passenger_wsgi.py +0 -212
  539. data/test/stub/wsgi/public/.gitignore +0 -0
  540. data/test/stub/wsgi/tmp/.gitignore +0 -0
  541. data/test/support/allocate_memory.c +0 -14
  542. data/test/support/apache2_controller.rb +0 -258
  543. data/test/support/multipart.rb +0 -62
  544. data/test/support/nginx_controller.rb +0 -97
  545. data/test/support/placebo-preloader.rb +0 -88
  546. data/test/support/test_helper.rb +0 -455
  547. data/test/support/valgrind.h +0 -2539
  548. data/test/tut/tut.h +0 -1310
  549. data/test/tut/tut_reporter.h +0 -256
  550. data/test/valgrind-osx.supp +0 -7
@@ -1,1463 +0,0 @@
1
- #include <TestSupport.h>
2
- #include <agents/HelperAgent/RequestHandler.h>
3
- #include <agents/HelperAgent/RequestHandler.cpp>
4
- #include <agents/HelperAgent/AgentOptions.h>
5
- #include <ApplicationPool2/Pool.h>
6
- #include <Utils/json.h>
7
- #include <Utils/IOUtils.h>
8
- #include <Utils/StrIntUtils.h>
9
- #include <Utils/Timer.h>
10
- #include <Utils/BufferedIO.h>
11
-
12
- #include <boost/shared_array.hpp>
13
- #include <string>
14
- #include <vector>
15
- #include <map>
16
- #include <sstream>
17
- #include <cstdarg>
18
- #include <sys/socket.h>
19
-
20
- using namespace std;
21
- using namespace boost;
22
- using namespace Passenger;
23
- using namespace Passenger::ApplicationPool2;
24
-
25
- namespace tut {
26
- struct RequestHandlerTest {
27
- InstanceDirectoryPtr instanceDir;
28
- string serverFilename;
29
- FileDescriptor requestSocket;
30
- AgentOptions agentOptions;
31
-
32
- BackgroundEventLoop bg;
33
- SpawnerFactoryPtr spawnerFactory;
34
- PoolPtr pool;
35
- Pool::DebugSupportPtr debug;
36
- boost::shared_ptr<RequestHandler> handler;
37
- FileDescriptor connection;
38
- map<string, string> defaultHeaders;
39
-
40
- string root;
41
- string rackAppPath, wsgiAppPath;
42
-
43
- RequestHandlerTest() {
44
- createInstanceDir(instanceDir);
45
- spawnerFactory = boost::make_shared<SpawnerFactory>(
46
- make_shared<SpawnerConfig>(*resourceLocator));
47
- pool = boost::make_shared<Pool>(spawnerFactory);
48
- pool->initialize();
49
- serverFilename = instanceDir->getPath() + "/server";
50
- requestSocket = createUnixServer(serverFilename);
51
- setNonBlocking(requestSocket);
52
- setLogLevel(LVL_WARN);
53
- setPrintAppOutputAsDebuggingMessages(true);
54
-
55
- agentOptions.passengerRoot = resourceLocator->getRoot();
56
- agentOptions.defaultRubyCommand = DEFAULT_RUBY;
57
- agentOptions.defaultUser = testConfig["default_user"].asString();
58
- agentOptions.defaultGroup = testConfig["default_group"].asString();
59
- root = resourceLocator->getRoot();
60
- rackAppPath = root + "/test/stub/rack";
61
- wsgiAppPath = root + "/test/stub/wsgi";
62
- defaultHeaders["PASSENGER_LOAD_SHELL_ENVVARS"] = "false";
63
- defaultHeaders["PASSENGER_APP_TYPE"] = "wsgi";
64
- defaultHeaders["PASSENGER_SPAWN_METHOD"] = "direct";
65
- defaultHeaders["REQUEST_METHOD"] = "GET";
66
- }
67
-
68
- ~RequestHandlerTest() {
69
- setLogLevel(DEFAULT_LOG_LEVEL);
70
- setPrintAppOutputAsDebuggingMessages(false);
71
- if (bg.isStarted()) {
72
- bg.safe->runSync(boost::bind(&RequestHandlerTest::destroy, this));
73
- } else {
74
- destroy();
75
- }
76
- unlink(serverFilename.c_str());
77
- }
78
-
79
- void init() {
80
- handler = boost::make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
81
- bg.start();
82
- }
83
-
84
- void destroy() {
85
- handler.reset();
86
- pool->destroy();
87
- pool.reset();
88
- ev_break(bg.loop, EVBREAK_ALL);
89
- }
90
-
91
- void initPoolDebugging() {
92
- pool->initDebugging();
93
- debug = pool->debugSupport;
94
- }
95
-
96
- FileDescriptor &connect() {
97
- connection = connectToUnixServer(serverFilename);
98
- return connection;
99
- }
100
-
101
- void sendHeaders(const map<string, string> &headers, const char *header1,
102
- const char *value1, ...)
103
- {
104
- va_list ap;
105
- const char *arg;
106
- map<string, string> finalHeaders;
107
- map<string, string>::const_iterator it;
108
- vector<StaticString> args;
109
- unsigned int totalSize = 0;
110
-
111
- for (it = headers.begin(); it != headers.end(); it++) {
112
- string key = string(it->first.data(), it->first.size() + 1);
113
- string value = string(it->second.data(), it->second.size() + 1);
114
- finalHeaders[key] = value;
115
- }
116
-
117
- finalHeaders[makeStaticStringWithNull(header1)] =
118
- makeStaticStringWithNull(value1);
119
-
120
- va_start(ap, value1);
121
- while ((arg = va_arg(ap, const char *)) != NULL) {
122
- string key(arg, strlen(arg) + 1);
123
- arg = va_arg(ap, const char *);
124
- string value(arg, strlen(arg) + 1);
125
- finalHeaders[key] = value;
126
- }
127
- va_end(ap);
128
-
129
- for (it = finalHeaders.begin(); it != finalHeaders.end(); it++) {
130
- args.push_back(it->first);
131
- args.push_back(it->second);
132
- totalSize += it->first.size();
133
- totalSize += it->second.size();
134
- }
135
-
136
- char totalSizeString[10];
137
- snprintf(totalSizeString, sizeof(totalSizeString), "%u:", totalSize);
138
- args.insert(args.begin(), StaticString(totalSizeString));
139
- args.push_back(",");
140
-
141
- gatheredWrite(connection, &args[0], args.size(), NULL);
142
- }
143
-
144
- string stripHeaders(const string &str) {
145
- string::size_type pos = str.find("\r\n\r\n");
146
- if (pos == string::npos) {
147
- return str;
148
- } else {
149
- string result = str;
150
- result.erase(0, pos + 4);
151
- return result;
152
- }
153
- }
154
-
155
- string inspect() {
156
- string result;
157
- bg.safe->runSync(boost::bind(&RequestHandlerTest::real_inspect, this, &result));
158
- return result;
159
- }
160
-
161
- void real_inspect(string *result) {
162
- stringstream stream;
163
- handler->inspect(stream);
164
- *result = stream.str();
165
- }
166
-
167
- static void writeBody(FileDescriptor conn, string body) {
168
- try {
169
- writeExact(conn, body);
170
- } catch (const SystemException &e) {
171
- if (e.code() == EPIPE) {
172
- // Ignore.
173
- } else {
174
- throw;
175
- }
176
- }
177
- }
178
- };
179
-
180
- DEFINE_TEST_GROUP_WITH_LIMIT(RequestHandlerTest, 80);
181
-
182
-
183
- /***** Basic tests *****/
184
-
185
- TEST_METHOD(1) {
186
- set_test_name("A request is forwarded to the app process, and its response is forwarded back.");
187
- init();
188
- connect();
189
- sendHeaders(defaultHeaders,
190
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
191
- "PATH_INFO", "/",
192
- NULL);
193
- string response = readAll(connection);
194
- string body = stripHeaders(response);
195
- ensure("Status line is correct", containsSubstring(response, "HTTP/1.1 200 OK\r\n"));
196
- ensure("Headers are correct", containsSubstring(response, "Content-Type: text/plain\r\n"));
197
- ensure("Contains a Status header", containsSubstring(response, "Status: 200 OK\r\n"));
198
- ensure_equals(body, "front page");
199
- }
200
-
201
- TEST_METHOD(2) {
202
- set_test_name("It can handle multiple requests in serial.");
203
- init();
204
- for (int i = 0; i < 10; i++) {
205
- connect();
206
- sendHeaders(defaultHeaders,
207
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
208
- "PATH_INFO", "/",
209
- NULL);
210
- string response = readAll(connection);
211
- string body = stripHeaders(response);
212
- ensure("Status line is correct", containsSubstring(response, "HTTP/1.1 200 OK\r\n"));
213
- ensure("Headers are correct", containsSubstring(response, "Content-Type: text/plain\r\n"));
214
- ensure("Contains a Status header", containsSubstring(response, "Status: 200 OK\r\n"));
215
- ensure_equals(body, "front page");
216
- }
217
- }
218
-
219
- TEST_METHOD(3) {
220
- set_test_name("It can handle request data that is sent piece-wise.");
221
- defaultHeaders["PASSENGER_APP_ROOT"] = wsgiAppPath;
222
- defaultHeaders["PATH_INFO"] = "/";
223
-
224
- string request;
225
- map<string, string>::const_iterator it, end = defaultHeaders.end();
226
- for (it = defaultHeaders.begin(); it != end; it++) {
227
- request.append(it->first);
228
- request.append(1, '\0');
229
- request.append(it->second);
230
- request.append(1, '\0');
231
- }
232
- request = toString(request.size()) + ":" + request;
233
- request.append(",");
234
-
235
- init();
236
- connect();
237
- string::size_type i = 0;
238
- while (i < request.size()) {
239
- const string piece = const_cast<const string &>(request).substr(i, 5);
240
- writeExact(connection, piece);
241
- usleep(10000);
242
- i += piece.size();
243
- }
244
-
245
- string response = readAll(connection);
246
- string body = stripHeaders(response);
247
- ensure("Status line is correct", containsSubstring(response, "HTTP/1.1 200 OK\r\n"));
248
- ensure("Headers are correct", containsSubstring(response, "Content-Type: text/plain\r\n"));
249
- ensure("Contains a Status header", containsSubstring(response, "Status: 200 OK\r\n"));
250
- ensure_equals(body, "front page");
251
- }
252
-
253
- TEST_METHOD(4) {
254
- set_test_name("It closes the connection with the application if the client has closed the connection.");
255
- init();
256
- connect();
257
- sendHeaders(defaultHeaders,
258
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
259
- "PATH_INFO", "/stream",
260
- NULL
261
- );
262
- BufferedIO io(connection);
263
- ensure_equals(io.readLine(), "HTTP/1.1 200 OK\r\n");
264
- ProcessPtr process;
265
- {
266
- LockGuard l(pool->syncher);
267
- ensure_equals(pool->getProcessCount(false), 1u);
268
- SuperGroupPtr superGroup = pool->superGroups.get(wsgiAppPath);
269
- process = superGroup->defaultGroup->enabledProcesses.front();
270
- ensure_equals(process->sessions, 1);
271
- }
272
- connection.close();
273
- EVENTUALLY(5,
274
- LockGuard l(pool->syncher);
275
- result = process->sessions == 0;
276
- );
277
- }
278
-
279
-
280
- /***** Connect password tests *****/
281
-
282
- TEST_METHOD(5) {
283
- set_test_name("It denies access if the connect password is wrong.");
284
- agentOptions.requestSocketPassword = "hello world";
285
- setLogLevel(LVL_ERROR);
286
- init();
287
-
288
- connect();
289
- writeExact(connection, "hello world");
290
- sendHeaders(defaultHeaders,
291
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
292
- "PATH_INFO", "/",
293
- NULL
294
- );
295
- ensure(containsSubstring(readAll(connection), "front page"));
296
-
297
- connect();
298
- try {
299
- sendHeaders(defaultHeaders,
300
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
301
- "PATH_INFO", "/",
302
- NULL
303
- );
304
- } catch (const SystemException &e) {
305
- ensure_equals(e.code(), EPIPE);
306
- return;
307
- }
308
- string response;
309
- try {
310
- response = readAll(connection);
311
- } catch (const SystemException &e) {
312
- ensure_equals(e.code(), ECONNRESET);
313
- return;
314
- }
315
- ensure_equals(response, "");
316
- }
317
-
318
- TEST_METHOD(6) {
319
- set_test_name("It disconnects the client if the connect password is not sent within a certain time.");
320
- agentOptions.requestSocketPassword = "hello world";
321
- setLogLevel(LVL_ERROR);
322
- handler = boost::make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
323
- handler->connectPasswordTimeout = 40;
324
- bg.start();
325
-
326
- connect();
327
- Timer timer;
328
- readAll(connection);
329
- timer.stop();
330
- ensure(timer.elapsed() <= 60);
331
- }
332
-
333
- TEST_METHOD(7) {
334
- set_test_name("It works correctly if the connect password is sent piece-wise.");
335
- agentOptions.requestSocketPassword = "hello world";
336
- init();
337
- connect();
338
- writeExact(connection, "hello");
339
- usleep(10000);
340
- writeExact(connection, " world");
341
- usleep(10000);
342
- sendHeaders(defaultHeaders,
343
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
344
- "PATH_INFO", "/",
345
- NULL
346
- );
347
- ensure(containsSubstring(readAll(connection), "front page"));
348
- }
349
-
350
-
351
- /***** Error page tests *****/
352
-
353
- TEST_METHOD(10) {
354
- set_test_name("If the app crashes at startup without an error page, "
355
- "and friendly error pages are turned on, then it renders a generic error page.");
356
- TempDir tempdir("tmp.handler");
357
- writeFile("tmp.handler/start.rb",
358
- "STDERR.puts 'I have failed'");
359
-
360
- setLogLevel(LVL_CRIT);
361
- init();
362
- connect();
363
- sendHeaders(defaultHeaders,
364
- "PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
365
- "PASSENGER_APP_TYPE", "",
366
- "PASSENGER_START_COMMAND", ("ruby\t" + root + "/test/tmp.handler/start.rb").c_str(),
367
- "PASSENGER_FRIENDLY_ERROR_PAGES", "true",
368
- "PATH_INFO", "/",
369
- NULL);
370
- string response = readAll(connection);
371
- ensure(containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
372
- ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
373
- ensure(containsSubstring(response, "I have failed"));
374
- }
375
-
376
- TEST_METHOD(11) {
377
- set_test_name("If the app crashes at startup with an error page, "
378
- "and friendly error pages are turned on, then it renders a friendly error page.");
379
- TempDir tempdir("tmp.handler");
380
- writeFile("tmp.handler/start.rb",
381
- "STDERR.puts 'Error'\n"
382
- "STDERR.puts\n"
383
- "STDERR.puts 'I have failed'\n");
384
-
385
- setLogLevel(LVL_CRIT);
386
- init();
387
- connect();
388
- sendHeaders(defaultHeaders,
389
- "PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
390
- "PASSENGER_APP_TYPE", "",
391
- "PASSENGER_START_COMMAND", ("ruby\t" + root + "/test/tmp.handler/start.rb").c_str(),
392
- "PASSENGER_FRIENDLY_ERROR_PAGES", "true",
393
- "PATH_INFO", "/",
394
- NULL);
395
- string response = readAll(connection);
396
- ensure(containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
397
- ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
398
- ensure(containsSubstring(response, "Content-Type: text/html; charset=UTF-8\r\n"));
399
- ensure(containsSubstring(response, "<html>"));
400
- ensure(containsSubstring(response, "I have failed"));
401
- }
402
-
403
- TEST_METHOD(12) {
404
- set_test_name("If spawning fails because of an internal error, "
405
- "and friendly error pages are on, then it reports the error appropriately.");
406
- TempDir tempdir("tmp.handler");
407
- writeFile("tmp.handler/start.rb", "");
408
-
409
- setLogLevel(LVL_CRIT);
410
- init();
411
- connect();
412
- sendHeaders(defaultHeaders,
413
- "PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
414
- "PASSENGER_APP_TYPE", "",
415
- "PASSENGER_START_COMMAND", ("ruby\t" + root + "/test/tmp.handler/start.rb").c_str(),
416
- "PASSENGER_FRIENDLY_ERROR_PAGES", "true",
417
- "PASSENGER_RAISE_INTERNAL_ERROR", "true",
418
- "PATH_INFO", "/",
419
- NULL);
420
- string response = readAll(connection);
421
- ensure("(1)", containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
422
- ensure("(2)", containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
423
- ensure("(3)", containsSubstring(response, "Content-Type: text/html; charset=UTF-8\r\n"));
424
- ensure("(4)", containsSubstring(response, "<html>"));
425
- ensure("(5)", containsSubstring(response, "An internal error occurred while trying to spawn the application."));
426
- ensure("(6)", containsSubstring(response, "RuntimeException"));
427
- ensure("(7)", containsSubstring(response, "An internal error!"));
428
- ensure("(8)", containsSubstring(response, "Spawner.h"));
429
- }
430
-
431
- TEST_METHOD(13) {
432
- set_test_name("Error pages respect the PASSENGER_STATUS_LINE option.");
433
- TempDir tempdir("tmp.handler");
434
- writeFile("tmp.handler/start.rb",
435
- "STDERR.puts 'I have failed'");
436
-
437
- setLogLevel(LVL_CRIT);
438
- init();
439
- connect();
440
- sendHeaders(defaultHeaders,
441
- "PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
442
- "PASSENGER_APP_TYPE", "",
443
- "PASSENGER_START_COMMAND", ("ruby\t" + root + "/test/tmp.handler/start.rb").c_str(),
444
- "PASSENGER_FRIENDLY_ERROR_PAGES", "true",
445
- "PASSENGER_STATUS_LINE", "false",
446
- "PATH_INFO", "/",
447
- NULL);
448
- string response = readAll(connection);
449
- ensure(!containsSubstring(response, "HTTP/1.1 "));
450
- ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
451
- ensure(containsSubstring(response, "I have failed"));
452
- }
453
-
454
- TEST_METHOD(14) {
455
- set_test_name("If PASSENGER_FRIENDLY_ERROR_PAGES is false then it does not render a friendly error page.");
456
- TempDir tempdir("tmp.handler");
457
- writeFile("tmp.handler/start.rb",
458
- "STDERR.puts 'Error'\n"
459
- "STDERR.puts\n"
460
- "STDERR.puts 'I have failed'\n");
461
-
462
- setLogLevel(LVL_CRIT);
463
- init();
464
- connect();
465
- sendHeaders(defaultHeaders,
466
- "PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
467
- "PASSENGER_APP_TYPE", "",
468
- "PASSENGER_START_COMMAND", ("ruby\t" + root + "/test/tmp.handler/start.rb").c_str(),
469
- "PASSENGER_FRIENDLY_ERROR_PAGES", "false",
470
- "PATH_INFO", "/",
471
- NULL);
472
- string response = readAll(connection);
473
- ensure(containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
474
- ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
475
- ensure(containsSubstring(response, "Content-Type: text/html; charset=UTF-8\r\n"));
476
- ensure(containsSubstring(response, "<html>"));
477
- ensure(!containsSubstring(response, "I have failed"));
478
- ensure(containsSubstring(response, "We're sorry, but something went wrong"));
479
- }
480
-
481
-
482
- /***** Buffering tests *****/
483
-
484
- TEST_METHOD(21) {
485
- set_test_name("If PASSENGER_BUFFERING is true, and Content-Length is given, it buffers the request body.");
486
- DeleteFileEventually file("tmp.output");
487
-
488
- init();
489
- connect();
490
- sendHeaders(defaultHeaders,
491
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
492
- "PASSENGER_BUFFERING", "true",
493
- "REQUEST_METHOD", "POST",
494
- "PATH_INFO", "/raw_upload_to_file",
495
- "CONTENT_LENGTH", "12",
496
- "HTTP_X_OUTPUT", (root + "/test/tmp.output").c_str(),
497
- NULL);
498
- writeExact(connection, "hello\n");
499
- SHOULD_NEVER_HAPPEN(200,
500
- result = fileExists("tmp.output");
501
- );
502
- writeExact(connection, "world\n");
503
- EVENTUALLY(1,
504
- result = fileExists("tmp.output");
505
- );
506
- ensure_equals(stripHeaders(readAll(connection)), "ok");
507
- }
508
-
509
- TEST_METHOD(22) {
510
- set_test_name("If PASSENGER_BUFFERING is true, and Transfer-Encoding is given, it buffers the request body.");
511
- DeleteFileEventually file("tmp.output");
512
-
513
- init();
514
- connect();
515
- sendHeaders(defaultHeaders,
516
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
517
- "PASSENGER_BUFFERING", "true",
518
- "REQUEST_METHOD", "POST",
519
- "PATH_INFO", "/raw_upload_to_file",
520
- "HTTP_TRANSFER_ENCODING", "chunked",
521
- "HTTP_X_OUTPUT", (root + "/test/tmp.output").c_str(),
522
- NULL);
523
- writeExact(connection, "hello\n");
524
- SHOULD_NEVER_HAPPEN(200,
525
- result = fileExists("tmp.output");
526
- );
527
- writeExact(connection, "world\n");
528
- SHOULD_NEVER_HAPPEN(200,
529
- result = fileExists("tmp.output");
530
- );
531
- shutdown(connection, SHUT_WR);
532
- ensure_equals(stripHeaders(readAll(connection)), "ok");
533
- }
534
-
535
- TEST_METHOD(24) {
536
- set_test_name("Test buffering of large request bodies that fit in neither the socket "
537
- "buffer nor the FileBackedPipe memory buffer, and that the application "
538
- "cannot read quickly enough.");
539
-
540
- DeleteFileEventually d1("/tmp/wait.txt");
541
- DeleteFileEventually d2("/tmp/output.txt");
542
-
543
- // 2.6 MB of request body. Guaranteed not to fit in any socket buffer.
544
- string requestBody;
545
- for (int i = 0; i < 204800; i++) {
546
- requestBody.append("hello world!\n");
547
- }
548
-
549
- init();
550
- connect();
551
- sendHeaders(defaultHeaders,
552
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
553
- "REQUEST_METHOD", "POST",
554
- "PATH_INFO", "/raw_upload_to_file",
555
- "PASSENGER_BUFFERING", "true",
556
- "CONTENT_LENGTH", toString(requestBody.size()).c_str(),
557
- "HTTP_X_WAIT_FOR_FILE", "/tmp/wait.txt",
558
- "HTTP_X_OUTPUT", "/tmp/output.txt",
559
- NULL);
560
-
561
- // Should not block.
562
- writeExact(connection, requestBody);
563
- shutdown(connection, SHUT_WR);
564
-
565
- EVENTUALLY(5,
566
- result = containsSubstring(inspect(), "session initiated = true");
567
- );
568
- touchFile("/tmp/wait.txt");
569
-
570
- string result = stripHeaders(readAll(connection));
571
- ensure_equals(result, "ok");
572
- struct stat buf;
573
- ensure(stat("/tmp/output.txt", &buf) == 0);
574
- ensure_equals(buf.st_size, (off_t) requestBody.size());
575
- }
576
-
577
- TEST_METHOD(25) {
578
- set_test_name("Test handling of slow clients that can't receive response data fast enough (response buffering).");
579
- init();
580
- connect();
581
- sendHeaders(defaultHeaders,
582
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
583
- "PATH_INFO", "/blob",
584
- "HTTP_X_SIZE", "10485760",
585
- NULL);
586
- EVENTUALLY(10,
587
- result = containsSubstring(inspect(), "appInput reachedEnd = true");
588
- );
589
- string result = stripHeaders(readAll(connection));
590
- ensure_equals(result.size(), 10485760u);
591
- const char *data = result.data();
592
- const char *end = result.data() + result.size();
593
- while (data < end) {
594
- ensure_equals(*data, 'x');
595
- data++;
596
- }
597
- }
598
-
599
-
600
- /***** Header handling tests *****/
601
-
602
- TEST_METHOD(26) {
603
- set_test_name("It replaces HTTP_CONTENT_LENGTH with CONTENT_LENGTH.");
604
- init();
605
- connect();
606
- sendHeaders(defaultHeaders,
607
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
608
- "REQUEST_METHOD", "POST",
609
- "PATH_INFO", "/env",
610
- "HTTP_CONTENT_LENGTH", "5",
611
- NULL);
612
- writeExact(connection, "hello");
613
- string response = readAll(connection);
614
- ensure(containsSubstring(response, "CONTENT_LENGTH = 5\n"));
615
- ensure(!containsSubstring(response, "HTTP_CONTENT_LENGTH"));
616
- }
617
-
618
- TEST_METHOD(27) {
619
- set_test_name("It replaces HTTP_CONTENT_TYPE with CONTENT_TYPE.");
620
- init();
621
- connect();
622
- sendHeaders(defaultHeaders,
623
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
624
- "PATH_INFO", "/env",
625
- "HTTP_CONTENT_TYPE", "application/json",
626
- NULL);
627
- string response = readAll(connection);
628
- ensure(containsSubstring(response, "CONTENT_TYPE = application/json\n"));
629
- ensure(!containsSubstring(response, "HTTP_CONTENT_TYPE"));
630
- }
631
-
632
- TEST_METHOD(28) {
633
- set_test_name("The response doesn't contain an HTTP status line if PASSENGER_STATUS_LINE is false.");
634
- init();
635
- connect();
636
- sendHeaders(defaultHeaders,
637
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
638
- "PASSENGER_STATUS_LINE", "false",
639
- "PATH_INFO", "/",
640
- NULL);
641
- string response = readAll(connection);
642
- ensure(!containsSubstring(response, "HTTP/1.1 "));
643
- ensure(containsSubstring(response, "Status: 200 OK\r\n"));
644
- }
645
-
646
- TEST_METHOD(29) {
647
- set_test_name("If the application outputs a status line without a reason phrase, then a reason phrase is automatically appended.");
648
- init();
649
- connect();
650
- sendHeaders(defaultHeaders,
651
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
652
- "PATH_INFO", "/custom_status",
653
- "HTTP_X_CUSTOM_STATUS", "201",
654
- NULL);
655
- string response = readAll(connection);
656
- ensure(containsSubstring(response, "HTTP/1.1 201 Created\r\n"));
657
- ensure(containsSubstring(response, "Status: 201 Created\r\n"));
658
- }
659
-
660
- TEST_METHOD(30) {
661
- set_test_name("If the application outputs a status line with a custom reason phrase, then that reason phrase is used.");
662
- init();
663
- connect();
664
- sendHeaders(defaultHeaders,
665
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
666
- "PATH_INFO", "/custom_status",
667
- "HTTP_X_CUSTOM_STATUS", "201 Bunnies Jump",
668
- NULL);
669
- string response = readAll(connection);
670
- ensure(containsSubstring(response, "HTTP/1.1 201 Bunnies Jump\r\n"));
671
- ensure(containsSubstring(response, "Status: 201 Bunnies Jump\r\n"));
672
- }
673
-
674
- TEST_METHOD(31) {
675
- set_test_name("It appends a Date header if the app doesn't output one.");
676
-
677
- init();
678
- connect();
679
- sendHeaders(defaultHeaders,
680
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
681
- "PATH_INFO", "/pid",
682
- NULL);
683
-
684
- string result = readAll(connection);
685
- ensure(result.find("Date: ") != string::npos);
686
- }
687
-
688
- TEST_METHOD(32) {
689
- set_test_name("It rejects non-GET, non-HEAD requests with an Upgrade header.");
690
-
691
- init();
692
- connect();
693
- sendHeaders(defaultHeaders,
694
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
695
- "PATH_INFO", "/",
696
- "REQUEST_METHOD", "POST",
697
- "HTTP_UPGRADE", "WebSocket",
698
- NULL);
699
- string response = readAll(connection);
700
- ensure(containsSubstring(response, "HTTP/1.1 400 Bad Request"));
701
- }
702
-
703
- TEST_METHOD(33) {
704
- set_test_name("It accepts GET/HEAD requests with a Content-Length header.");
705
-
706
- DeleteFileEventually d("/tmp/output.txt");
707
-
708
- init();
709
- connect();
710
- sendHeaders(defaultHeaders,
711
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
712
- "PATH_INFO", "/raw_upload_to_file",
713
- "REQUEST_METHOD", "GET",
714
- "CONTENT_LENGTH", "2",
715
- "HTTP_X_OUTPUT", "/tmp/output.txt",
716
- NULL);
717
- writeExact(connection, "hi");
718
-
719
- string result = stripHeaders(readAll(connection));
720
- ensure_equals(result, "ok");
721
- ensure_equals(readAll("/tmp/output.txt"), "hi");
722
-
723
- connect();
724
- sendHeaders(defaultHeaders,
725
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
726
- "PATH_INFO", "/raw_upload_to_file",
727
- "REQUEST_METHOD", "HEAD",
728
- "CONTENT_LENGTH", "2",
729
- "HTTP_X_OUTPUT", "/tmp/output.txt",
730
- NULL);
731
- writeExact(connection, "ho");
732
-
733
- result = stripHeaders(readAll(connection));
734
- ensure_equals(result, "ok");
735
- ensure_equals(readAll("/tmp/output.txt"), "ho");
736
- }
737
-
738
- TEST_METHOD(34) {
739
- set_test_name("It rejects GET/HEAD requests with a Transfer-Encoding header.");
740
-
741
- DeleteFileEventually d("/tmp/output.txt");
742
-
743
- init();
744
- connect();
745
- sendHeaders(defaultHeaders,
746
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
747
- "PATH_INFO", "/raw_upload_to_file",
748
- "REQUEST_METHOD", "GET",
749
- "HTTP_TRANSFER_ENCODING", "chunked",
750
- "HTTP_X_OUTPUT", "/tmp/output.txt",
751
- NULL);
752
- writeExact(connection, "hi");
753
- shutdown(connection, SHUT_WR);
754
-
755
- string result = stripHeaders(readAll(connection));
756
- ensure_equals(result, "ok");
757
- ensure_equals(readAll("/tmp/output.txt"), "hi");
758
-
759
- connect();
760
- sendHeaders(defaultHeaders,
761
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
762
- "PATH_INFO", "/raw_upload_to_file",
763
- "REQUEST_METHOD", "HEAD",
764
- "HTTP_TRANSFER_ENCODING", "chunked",
765
- "HTTP_X_OUTPUT", "/tmp/output.txt",
766
- NULL);
767
- writeExact(connection, "ho");
768
- shutdown(connection, SHUT_WR);
769
-
770
- result = stripHeaders(readAll(connection));
771
- ensure_equals(result, "ok");
772
- ensure_equals(readAll("/tmp/output.txt"), "ho");
773
- }
774
-
775
-
776
- /***** Advanced connection handling tests *****/
777
-
778
- TEST_METHOD(40) {
779
- set_test_name("It streams the request body to the application.");
780
- DeleteFileEventually file("tmp.output");
781
-
782
- init();
783
- connect();
784
- sendHeaders(defaultHeaders,
785
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
786
- "REQUEST_METHOD", "POST",
787
- "PATH_INFO", "/raw_upload_to_file",
788
- "HTTP_TRANSFER_ENCODING", "chunked",
789
- "HTTP_X_OUTPUT", (root + "/test/tmp.output").c_str(),
790
- NULL);
791
- writeExact(connection, "hello\n");
792
- EVENTUALLY(5,
793
- result = fileExists("tmp.output") && readAll("tmp.output") == "hello\n";
794
- );
795
- writeExact(connection, "world\n");
796
- EVENTUALLY(3,
797
- result = readAll("tmp.output") == "hello\nworld\n";
798
- );
799
- shutdown(connection, SHUT_WR);
800
- ensure_equals(stripHeaders(readAll(connection)), "ok");
801
- }
802
-
803
- TEST_METHOD(41) {
804
- set_test_name("If no Content-Length and no Transfer-Encoding are given, and buffering is on: "
805
- "it does not pass any request body data.");
806
-
807
- DeleteFileEventually d("/tmp/output.txt");
808
-
809
- init();
810
- connect();
811
- sendHeaders(defaultHeaders,
812
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
813
- "PATH_INFO", "/raw_upload_to_file",
814
- "REQUEST_METHOD", "POST",
815
- "PASSENGER_BUFFERING", "true",
816
- "HTTP_X_OUTPUT", "/tmp/output.txt",
817
- NULL);
818
- writeExact(connection, "hello\n");
819
-
820
- string result = stripHeaders(readAll(connection));
821
- ensure_equals(result, "ok");
822
- struct stat buf;
823
- ensure(stat("/tmp/output.txt", &buf) == 0);
824
- ensure_equals(buf.st_size, (off_t) 0);
825
- }
826
-
827
- TEST_METHOD(42) {
828
- set_test_name("If no Content-Length and no Transfer-Encoding are given, and buffering is off: "
829
- "it does not pass any request body data.");
830
-
831
- DeleteFileEventually d("/tmp/output.txt");
832
-
833
- init();
834
- connect();
835
- sendHeaders(defaultHeaders,
836
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
837
- "PATH_INFO", "/raw_upload_to_file",
838
- "REQUEST_METHOD", "POST",
839
- "HTTP_X_OUTPUT", "/tmp/output.txt",
840
- NULL);
841
- writeExact(connection, "hello\n");
842
-
843
- string result = stripHeaders(readAll(connection));
844
- ensure_equals(result, "ok");
845
- struct stat buf;
846
- ensure(stat("/tmp/output.txt", &buf) == 0);
847
- ensure_equals(buf.st_size, (off_t) 0);
848
- }
849
-
850
- TEST_METHOD(43) {
851
- set_test_name("If Upgrade is given, it keeps passing the request body until end of stream.");
852
-
853
- DeleteFileEventually d("/tmp/output.txt");
854
-
855
- init();
856
- connect();
857
- sendHeaders(defaultHeaders,
858
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
859
- "PATH_INFO", "/raw_upload_to_file",
860
- "HTTP_UPGRADE", "websocket",
861
- "HTTP_X_OUTPUT", "/tmp/output.txt",
862
- NULL);
863
- writeExact(connection, "hello\n");
864
- shutdown(connection, SHUT_WR);
865
-
866
- string result = stripHeaders(readAll(connection));
867
- ensure_equals(result, "ok");
868
- struct stat buf;
869
- ensure(stat("/tmp/output.txt", &buf) == 0);
870
- ensure_equals(buf.st_size, (off_t) 6);
871
- }
872
-
873
- TEST_METHOD(45) {
874
- set_test_name("If Content-Length is given, buffering is on, and request body is large: "
875
- "it passes Content-Length bytes of the request body.");
876
-
877
- DeleteFileEventually d("/tmp/output.txt");
878
-
879
- // 2.6 MB of request body. Guaranteed not to fit in any socket buffer.
880
- string requestBody;
881
- for (int i = 0; i < 204800; i++) {
882
- requestBody.append("hello world!\n");
883
- }
884
-
885
- init();
886
- connect();
887
- sendHeaders(defaultHeaders,
888
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
889
- "PATH_INFO", "/raw_upload_to_file",
890
- "REQUEST_METHOD", "POST",
891
- "CONTENT_LENGTH", toString(requestBody.size()).c_str(),
892
- "PASSENGER_BUFFERING", "true",
893
- "HTTP_X_OUTPUT", "/tmp/output.txt",
894
- NULL);
895
- writeExact(connection, requestBody);
896
-
897
- string result = stripHeaders(readAll(connection));
898
- ensure_equals(result, "ok");
899
- struct stat buf;
900
- ensure(stat("/tmp/output.txt", &buf) == 0);
901
- ensure_equals(buf.st_size, (off_t) requestBody.size());
902
- }
903
-
904
- TEST_METHOD(46) {
905
- set_test_name("If Content-Length is given, buffering is on, and request body is small: "
906
- "it passes Content-Length bytes of the request body.");
907
-
908
- DeleteFileEventually d("/tmp/output.txt");
909
- string requestBody = "hello world";
910
-
911
- init();
912
- connect();
913
- sendHeaders(defaultHeaders,
914
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
915
- "PATH_INFO", "/raw_upload_to_file",
916
- "REQUEST_METHOD", "POST",
917
- "CONTENT_LENGTH", toString(requestBody.size()).c_str(),
918
- "PASSENGER_BUFFERING", "true",
919
- "HTTP_X_OUTPUT", "/tmp/output.txt",
920
- NULL);
921
- writeExact(connection, requestBody);
922
-
923
- string result = stripHeaders(readAll(connection));
924
- ensure_equals(result, "ok");
925
- struct stat buf;
926
- ensure(stat("/tmp/output.txt", &buf) == 0);
927
- ensure_equals(buf.st_size, (off_t) requestBody.size());
928
- }
929
-
930
- TEST_METHOD(47) {
931
- set_test_name("If Content-Length is given, buffering is off, and request body is large: "
932
- "it passes Content-Length bytes of the request body.");
933
-
934
- DeleteFileEventually d("/tmp/output.txt");
935
-
936
- // 2 MB of request body. Guaranteed not to fit in any socket buffer.
937
- string requestBody;
938
- for (int i = 0; i < 102400; i++) {
939
- char buf[100];
940
- snprintf(buf, sizeof(buf), "%06d: hello world!\n", i);
941
- requestBody.append(buf);
942
- }
943
-
944
- init();
945
- connect();
946
- sendHeaders(defaultHeaders,
947
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
948
- "PATH_INFO", "/raw_upload_to_file",
949
- "REQUEST_METHOD", "POST",
950
- "CONTENT_LENGTH", toString(requestBody.size()).c_str(),
951
- "HTTP_X_OUTPUT", "/tmp/output.txt",
952
- NULL);
953
-
954
- TempThread thr(boost::bind(RequestHandlerTest::writeBody, connection, requestBody));
955
-
956
- string result = stripHeaders(readAll(connection));
957
- ensure_equals(result, "ok");
958
- struct stat buf;
959
- ensure(stat("/tmp/output.txt", &buf) == 0);
960
- ensure_equals(buf.st_size, (off_t) requestBody.size());
961
- }
962
-
963
- TEST_METHOD(48) {
964
- set_test_name("If Content-Length is given, buffering is off, and request body is small: "
965
- "it passes Content-Length bytes of the request body.");
966
-
967
- DeleteFileEventually d("/tmp/output.txt");
968
- string requestBody = "hello world";
969
-
970
- init();
971
- connect();
972
- sendHeaders(defaultHeaders,
973
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
974
- "PATH_INFO", "/raw_upload_to_file",
975
- "REQUEST_METHOD", "POST",
976
- "CONTENT_LENGTH", toString(requestBody.size()).c_str(),
977
- "HTTP_X_OUTPUT", "/tmp/output.txt",
978
- NULL);
979
-
980
- TempThread thr(boost::bind(RequestHandlerTest::writeBody, connection, requestBody));
981
-
982
- string result = stripHeaders(readAll(connection));
983
- ensure_equals(result, "ok");
984
- struct stat buf;
985
- ensure(stat("/tmp/output.txt", &buf) == 0);
986
- ensure_equals(buf.st_size, (off_t) requestBody.size());
987
- }
988
-
989
- TEST_METHOD(49) {
990
- set_test_name("If Transfer-Encoding is given and buffering is on: "
991
- "it keeps passing the request body until end of stream.");
992
-
993
- DeleteFileEventually d("/tmp/output.txt");
994
-
995
- // 2.6 MB of request body. Guaranteed not to fit in any socket buffer.
996
- string requestBody;
997
- for (int i = 0; i < 204800; i++) {
998
- requestBody.append("hello world!\n");
999
- }
1000
-
1001
- init();
1002
- connect();
1003
- sendHeaders(defaultHeaders,
1004
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1005
- "PATH_INFO", "/raw_upload_to_file",
1006
- "REQUEST_METHOD", "POST",
1007
- "PASSENGER_BUFFERING", "true",
1008
- "HTTP_TRANSFER_ENCODING", "chunked",
1009
- "HTTP_X_OUTPUT", "/tmp/output.txt",
1010
- NULL);
1011
- writeExact(connection, requestBody);
1012
- shutdown(connection, SHUT_WR);
1013
-
1014
- string result = stripHeaders(readAll(connection));
1015
- ensure_equals(result, "ok");
1016
- struct stat buf;
1017
- ensure(stat("/tmp/output.txt", &buf) == 0);
1018
- ensure_equals(buf.st_size, (off_t) requestBody.size());
1019
- }
1020
-
1021
- TEST_METHOD(50) {
1022
- set_test_name("If Transfer-Encoding is given and buffering is off: "
1023
- "it keeps passing the request body until end of stream.");
1024
-
1025
- DeleteFileEventually d("/tmp/output.txt");
1026
-
1027
- // 2.6 MB of request body. Guaranteed not to fit in any socket buffer.
1028
- string requestBody;
1029
- for (int i = 0; i < 204800; i++) {
1030
- requestBody.append("hello world!\n");
1031
- }
1032
-
1033
- init();
1034
- connect();
1035
- sendHeaders(defaultHeaders,
1036
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1037
- "PATH_INFO", "/raw_upload_to_file",
1038
- "REQUEST_METHOD", "POST",
1039
- "HTTP_TRANSFER_ENCODING", "chunked",
1040
- "HTTP_X_OUTPUT", "/tmp/output.txt",
1041
- NULL);
1042
- writeExact(connection, requestBody);
1043
- shutdown(connection, SHUT_WR);
1044
-
1045
- string result = stripHeaders(readAll(connection));
1046
- ensure_equals(result, "ok");
1047
- struct stat buf;
1048
- ensure(stat("/tmp/output.txt", &buf) == 0);
1049
- ensure_equals(buf.st_size, (off_t) requestBody.size());
1050
- }
1051
-
1052
- TEST_METHOD(51) {
1053
- set_test_name("If Transfer-Encoding is given and the application socket uses the HTTP protocol, "
1054
- "rechunk the body when forwarding it to the application.");
1055
-
1056
- fprintf(stderr, "TODO: implement test 51\n");
1057
- }
1058
-
1059
- TEST_METHOD(54) {
1060
- set_test_name("It writes an appropriate response if the request queue is overflown.");
1061
-
1062
- initPoolDebugging();
1063
- debug->restarting = false;
1064
- debug->spawning = false;
1065
- debug->testOverflowRequestQueue = true;
1066
- init();
1067
- connect();
1068
- sendHeaders(defaultHeaders,
1069
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1070
- "PATH_INFO", "/",
1071
- NULL);
1072
- string response = readAll(connection);
1073
- ensure(response.find("Status: 503 Service Unavailable") != string::npos);
1074
- ensure(response.find("This website is under heavy load") != string::npos);
1075
- }
1076
-
1077
- TEST_METHOD(55) {
1078
- set_test_name("It uses the status code dictated by PASSENGER_REQUEST_QUEUE_OVERFLOW_STATUS_CODE "
1079
- "if the request queue is overflown");
1080
-
1081
- initPoolDebugging();
1082
- debug->restarting = false;
1083
- debug->spawning = false;
1084
- debug->testOverflowRequestQueue = true;
1085
- init();
1086
- connect();
1087
- sendHeaders(defaultHeaders,
1088
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1089
- "PATH_INFO", "/",
1090
- "PASSENGER_REQUEST_QUEUE_OVERFLOW_STATUS_CODE", "504",
1091
- NULL);
1092
- string response = readAll(connection);
1093
- ensure(response.find("Status: 504 Gateway Timeout") != string::npos);
1094
- ensure(response.find("This website is under heavy load") != string::npos);
1095
- }
1096
-
1097
- TEST_METHOD(56) {
1098
- set_test_name("PASSENGER_REQUEST_QUEUE_OVERFLOW_STATUS_CODE should work even if it is an unknown code");
1099
-
1100
- initPoolDebugging();
1101
- debug->restarting = false;
1102
- debug->spawning = false;
1103
- debug->testOverflowRequestQueue = true;
1104
- init();
1105
- connect();
1106
- sendHeaders(defaultHeaders,
1107
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1108
- "PATH_INFO", "/",
1109
- "PASSENGER_REQUEST_QUEUE_OVERFLOW_STATUS_CODE", "604",
1110
- NULL);
1111
- string response = readAll(connection);
1112
- ensure(response.find("Status: 604 Unknown Reason-Phrase") != string::npos);
1113
- ensure(response.find("This website is under heavy load") != string::npos);
1114
- }
1115
-
1116
- TEST_METHOD(57) {
1117
- set_test_name("It relieves the application process after having read its entire response data.");
1118
-
1119
- init();
1120
- connect();
1121
- sendHeaders(defaultHeaders,
1122
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1123
- "PATH_INFO", "/blob",
1124
- NULL);
1125
- vector<ProcessPtr> processes;
1126
- EVENTUALLY(5,
1127
- processes = pool->getProcesses();
1128
- result = processes.size() == 1;
1129
- );
1130
- EVENTUALLY(5,
1131
- LockGuard l(pool->syncher);
1132
- result = processes[0]->processed == 1;
1133
- );
1134
- {
1135
- LockGuard l(pool->syncher);
1136
- ensure_equals("The session is closed before the client is done reading",
1137
- processes[0]->sessions, 0);
1138
- }
1139
- }
1140
-
1141
- TEST_METHOD(58) {
1142
- set_test_name("It supports responses in chunked transfer encoding.");
1143
-
1144
- init();
1145
- connect();
1146
- sendHeaders(defaultHeaders,
1147
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1148
- "PATH_INFO", "/chunked_stream",
1149
- NULL
1150
- );
1151
-
1152
- char buf[1024 * 10];
1153
- unsigned long long timeout = 500000;
1154
- unsigned int size;
1155
- try {
1156
- size = readExact(connection, buf, sizeof(buf), &timeout);
1157
- } catch (const TimeoutException &) {
1158
- fail("RequestHandler did not correctly handle chunked EOF!");
1159
- }
1160
-
1161
- string response(buf, size);
1162
- string body = stripHeaders(response);
1163
- ensure(containsSubstring(response, "Counter: 0\n"));
1164
- ensure(containsSubstring(response, "Counter: 1\n"));
1165
- ensure(containsSubstring(response, "Counter: 2\n"));
1166
- }
1167
-
1168
- TEST_METHOD(59) {
1169
- set_test_name("It supports switching protocols when communicating over application session sockets.");
1170
-
1171
- init();
1172
- connect();
1173
- sendHeaders(defaultHeaders,
1174
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1175
- "PATH_INFO", "/switch_protocol",
1176
- "HTTP_UPGRADE", "raw",
1177
- "HTTP_CONNECTION", "Upgrade",
1178
- NULL
1179
- );
1180
-
1181
- BufferedIO io(connection);
1182
- string header;
1183
- bool done = false;
1184
-
1185
- ensure_equals(io.readLine(), "HTTP/1.1 101 Switching Protocols\r\n");
1186
-
1187
- do {
1188
- string line = io.readLine();
1189
- done = line.empty() || line == "\r\n";
1190
- if (!done) {
1191
- header.append(line);
1192
- }
1193
- } while (!done);
1194
-
1195
- ensure("(1)", containsSubstring(header, "Upgrade: raw\r\n"));
1196
- ensure("(2)", containsSubstring(header, "Connection: Upgrade\r\n"));
1197
-
1198
- writeExact(connection, "hello\n");
1199
- ensure_equals(io.readLine(), "Echo: hello\n");
1200
- }
1201
-
1202
- TEST_METHOD(60) {
1203
- set_test_name("It supports switching protocols when communication over application http_session sockets.");
1204
-
1205
- init();
1206
- connect();
1207
- sendHeaders(defaultHeaders,
1208
- "_PASSENGER_FORCE_HTTP_SESSION", "true",
1209
- "PASSENGER_APP_ROOT", rackAppPath.c_str(),
1210
- "PASSENGER_APP_TYPE", "rack",
1211
- "REQUEST_URI", "/switch_protocol",
1212
- "PATH_INFO", "/switch_protocol",
1213
- "HTTP_UPGRADE", "raw",
1214
- "HTTP_CONNECTION", "Upgrade",
1215
- NULL
1216
- );
1217
-
1218
- BufferedIO io(connection);
1219
- string header;
1220
- bool done = false;
1221
- vector<ProcessPtr> processes;
1222
-
1223
- ensure_equals(io.readLine(), "HTTP/1.1 101 Switching Protocols\r\n");
1224
- processes = pool->getProcesses();
1225
- {
1226
- LockGuard l(pool->syncher);
1227
- ProcessPtr process = processes[0];
1228
- ensure_equals(process->sessionSockets.top()->protocol, "http_session");
1229
- }
1230
-
1231
- do {
1232
- string line = io.readLine();
1233
- done = line.empty() || line == "\r\n";
1234
- if (!done) {
1235
- header.append(line);
1236
- }
1237
- } while (!done);
1238
-
1239
- ensure("(1)", containsSubstring(header, "Upgrade: raw\r\n"));
1240
- ensure("(2)", containsSubstring(header, "Connection: Upgrade\r\n"));
1241
-
1242
- writeExact(connection, "hello\n");
1243
- ensure_equals(io.readLine(), "Echo: hello\n");
1244
- }
1245
-
1246
- TEST_METHOD(61) {
1247
- set_test_name("If the response contains Transfer-Encoding chunked, "
1248
- "it dechunks the response body and forwards it until the "
1249
- "zero-length chunk is encountered.");
1250
-
1251
- init();
1252
- connect();
1253
- sendHeaders(defaultHeaders,
1254
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1255
- "PATH_INFO", "/chunked",
1256
- NULL);
1257
-
1258
- string response = readAll(connection);
1259
- string body = stripHeaders(response);
1260
- ensure_equals(body,
1261
- "chunk1\n"
1262
- "chunk2\n"
1263
- "chunk3\n");
1264
- }
1265
-
1266
- TEST_METHOD(62) {
1267
- set_test_name("If the response contains Transfer-Encoding chunked, "
1268
- "it closes the connection with the app when the zero-length chunk is encountered.");
1269
-
1270
- DeleteFileEventually statusFile("/tmp/passenger-tail-status.txt");
1271
- createFile("/tmp/passenger-tail-status.txt", "",
1272
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
1273
-
1274
- init();
1275
- connect();
1276
- sendHeaders(defaultHeaders,
1277
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1278
- "PATH_INFO", "/chunked",
1279
- "HTTP_X_SLEEP_WHEN_DONE", "0.01",
1280
- "HTTP_X_EXTRA_DATA", "true",
1281
- "HTTP_X_TAIL_STATUS_FILE", "/tmp/passenger-tail-status.txt",
1282
- NULL);
1283
-
1284
- string response = readAll(connection);
1285
- string body = stripHeaders(response);
1286
- ensure_equals(body,
1287
- "chunk1\n"
1288
- "chunk2\n"
1289
- "chunk3\n");
1290
- EVENTUALLY(5,
1291
- result = readAll("/tmp/passenger-tail-status.txt") == "False";
1292
- );
1293
- }
1294
-
1295
- TEST_METHOD(63) {
1296
- set_test_name("If the response contains Transfer-Encoding chunked, "
1297
- "it discards any additional response body data after the zero-length chunk is encountered.");
1298
-
1299
- init();
1300
- connect();
1301
- sendHeaders(defaultHeaders,
1302
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1303
- "PATH_INFO", "/chunked",
1304
- "HTTP_X_EXTRA_DATA", "true",
1305
- NULL);
1306
-
1307
- string response = readAll(connection);
1308
- string body = stripHeaders(response);
1309
- ensure_equals(body,
1310
- "chunk1\n"
1311
- "chunk2\n"
1312
- "chunk3\n");
1313
- }
1314
-
1315
- TEST_METHOD(64) {
1316
- set_test_name("If the response contains Content-Length, "
1317
- "it forwards exactly Content-Length bytes of the response body.");
1318
-
1319
- init();
1320
- connect();
1321
- sendHeaders(defaultHeaders,
1322
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1323
- "PATH_INFO", "/blob",
1324
- "HTTP_X_SIZE", "5000000",
1325
- "HTTP_X_CONTENT_LENGTH", "true",
1326
- NULL);
1327
-
1328
- string response = readAll(connection);
1329
- string body = stripHeaders(response);
1330
- FILE *f = fopen("/tmp/debug.txt", "w");
1331
- fwrite(response.data(), 1, response.size(), f);
1332
- fclose(f);
1333
- ensure_equals(body.size(), 5000000u);
1334
- }
1335
-
1336
- TEST_METHOD(65) {
1337
- set_test_name("If the response contains Content-Length, "
1338
- "it closes the connection with the app after forwarding exactly Content-Length bytes.");
1339
-
1340
- DeleteFileEventually statusFile("/tmp/passenger-tail-status.txt");
1341
- createFile("/tmp/passenger-tail-status.txt", "",
1342
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
1343
-
1344
- init();
1345
- connect();
1346
- sendHeaders(defaultHeaders,
1347
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1348
- "PATH_INFO", "/blob",
1349
- "HTTP_X_SIZE", "5000000",
1350
- "HTTP_X_CONTENT_LENGTH", "true",
1351
- "HTTP_X_SLEEP_WHEN_DONE", "0.01",
1352
- "HTTP_X_EXTRA_DATA", "true",
1353
- "HTTP_X_TAIL_STATUS_FILE", "/tmp/passenger-tail-status.txt",
1354
- NULL);
1355
-
1356
- string response = readAll(connection);
1357
- string body = stripHeaders(response);
1358
- ensure_equals(body.size(), 5000000u);
1359
- EVENTUALLY(5,
1360
- result = readAll("/tmp/passenger-tail-status.txt") == "False";
1361
- );
1362
- }
1363
-
1364
- TEST_METHOD(66) {
1365
- set_test_name("If the response contains Content-Length, "
1366
- "it discards any additional response body data after Content-Length bytes.");
1367
-
1368
- init();
1369
- connect();
1370
- sendHeaders(defaultHeaders,
1371
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1372
- "PATH_INFO", "/blob",
1373
- "HTTP_X_SIZE", "5000000",
1374
- "HTTP_X_CONTENT_LENGTH", "true",
1375
- "HTTP_X_EXTRA_DATA", "true",
1376
- NULL);
1377
-
1378
- string response = readAll(connection);
1379
- string body = stripHeaders(response);
1380
- ensure_equals(body.size(), 5000000u);
1381
- }
1382
-
1383
- TEST_METHOD(67) {
1384
- set_test_name("If the response contains neither Transfer-Encoding chunked nor Content-Length, "
1385
- "it forwards the response body until EOF.");
1386
-
1387
- init();
1388
- connect();
1389
- sendHeaders(defaultHeaders,
1390
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1391
- "PATH_INFO", "/blob",
1392
- "HTTP_X_SIZE", "5000000",
1393
- "HTTP_X_EXTRA_DATA", "true",
1394
- NULL);
1395
-
1396
- string response = readAll(connection);
1397
- string body = stripHeaders(response);
1398
- ensure_equals(body.size(), 5000004u);
1399
- }
1400
-
1401
-
1402
- /***** Out-of-band work tests *****/
1403
-
1404
- TEST_METHOD(75) {
1405
- set_test_name("If the application outputs a request oobw header, handler should remove the header, mark "
1406
- "the process as oobw requested. The process should continue to process requests until the "
1407
- "spawner spawns another process (to avoid the group being empty). As soon as the new "
1408
- "process is spawned, the original process will make the oobw request. Afterwards, the "
1409
- "original process is re-enabled.");
1410
- init();
1411
- connect();
1412
- sendHeaders(defaultHeaders,
1413
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1414
- "PATH_INFO", "/oobw",
1415
- NULL);
1416
- string response = readAll(connection);
1417
- ensure("status is not 200", containsSubstring(response, "Status: 200 OK\r\n"));
1418
- ensure("contains oowb header", !containsSubstring(response, "X-Passenger-Request-OOB-Work:"));
1419
- pid_t origPid = atoi(stripHeaders(response));
1420
-
1421
- // Get a reference to the orignal process and verify oobw has been requested.
1422
- ProcessPtr origProcess;
1423
- {
1424
- LockGuard l(pool->syncher);
1425
- origProcess = pool->superGroups.get(wsgiAppPath)->defaultGroup->disablingProcesses.front();
1426
- ensure("OOBW requested", origProcess->oobwStatus == Process::OOBW_IN_PROGRESS);
1427
- }
1428
- ensure("sanity check", origPid == origProcess->pid); // just a sanity check
1429
-
1430
- // Issue requests until the new process handles it.
1431
- pid_t pid;
1432
- EVENTUALLY(2,
1433
- connect();
1434
- sendHeaders(defaultHeaders,
1435
- "PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
1436
- "PATH_INFO", "/pid",
1437
- NULL);
1438
- string response = readAll(connection);
1439
- ensure("status is 200", containsSubstring(response, "Status: 200 OK\r\n"));
1440
- pid = atoi(stripHeaders(response));
1441
- result = (pid != origPid);
1442
- );
1443
-
1444
- // Wait for the original process to finish oobw request.
1445
- EVENTUALLY(2,
1446
- boost::unique_lock<boost::mutex> lock(pool->syncher);
1447
- result = origProcess->oobwStatus == Process::OOBW_NOT_ACTIVE;
1448
- );
1449
-
1450
- // Final asserts.
1451
- {
1452
- boost::unique_lock<boost::mutex> lock(pool->syncher);
1453
- ensure_equals("2 enabled processes", pool->superGroups.get(wsgiAppPath)->defaultGroup->enabledProcesses.size(), 2u);
1454
- ensure_equals("oobw is reset", origProcess->oobwStatus, Process::OOBW_NOT_ACTIVE);
1455
- ensure_equals("process is enabled", origProcess->enabled, Process::ENABLED);
1456
- }
1457
- }
1458
-
1459
- // Test small response buffering.
1460
- // Test large response buffering.
1461
-
1462
- /***************************/
1463
- }