passenger 2.0.6 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data/DEVELOPERS.TXT +10 -4
- data/LICENSE +1 -1
- data/NEWS +0 -0
- data/Rakefile +183 -117
- data/benchmark/dispatcher.rb +5 -9
- data/bin/passenger-install-apache2-module +52 -18
- data/bin/passenger-memory-stats +67 -13
- data/bin/passenger-spawn-server +8 -4
- data/bin/passenger-status +21 -46
- data/bin/passenger-stress-test +5 -5
- data/debian/postinst +1 -1
- data/doc/ApplicationPool algorithm.txt +180 -128
- data/doc/Architectural overview.html +1 -778
- data/doc/Security of user switching support.html +1 -643
- data/doc/Users guide Apache.html +3127 -0
- data/doc/Users guide Nginx.html +1458 -0
- data/doc/Users guide.html +1404 -467
- data/doc/Users guide.txt +843 -105
- data/doc/cxxapi/ApplicationPoolServer_8h-source.html +751 -641
- data/doc/cxxapi/ApplicationPool_8h-source.html +168 -171
- data/doc/cxxapi/Application_8h-source.html +494 -394
- data/doc/cxxapi/Bucket_8h-source.html +21 -15
- data/doc/cxxapi/CachedFileStat_8h-source.html +191 -0
- data/doc/cxxapi/Configuration_8h-source.html +311 -149
- data/doc/cxxapi/DirectoryMapper_8h-source.html +309 -0
- data/doc/cxxapi/DummySpawnManager_8h-source.html +3 -4
- data/doc/cxxapi/Exceptions_8h-source.html +182 -165
- data/doc/cxxapi/FileChecker_8h-source.html +130 -0
- data/doc/cxxapi/Hooks_8h-source.html +2 -3
- data/doc/cxxapi/Logging_8h-source.html +92 -89
- data/doc/cxxapi/MessageChannel_8h-source.html +585 -477
- data/doc/cxxapi/PoolOptions_8h-source.html +305 -0
- data/doc/cxxapi/SpawnManager_8h-source.html +515 -540
- data/doc/cxxapi/StandardApplicationPool_8h-source.html +779 -679
- data/doc/cxxapi/SystemTime_8h-source.html +104 -0
- data/doc/cxxapi/Utils_8h-source.html +331 -227
- data/doc/cxxapi/annotated.html +6 -7
- data/doc/cxxapi/classClient-members.html +1 -2
- data/doc/cxxapi/classClient.html +1 -2
- data/doc/cxxapi/classHooks-members.html +5 -2
- data/doc/cxxapi/classHooks.html +112 -2
- data/doc/cxxapi/classPassenger_1_1Application-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1Application.html +8 -9
- data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +42 -81
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +3 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +3 -2
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +74 -3
- data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1BusyException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +38 -0
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +256 -0
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +2 -3
- data/doc/cxxapi/{classPassenger_1_1Thread-members.html → classPassenger_1_1FileChecker-members.html} +4 -5
- data/doc/cxxapi/classPassenger_1_1FileChecker.html +121 -0
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileSystemException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1IOException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +5 -2
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +155 -5
- data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption-members.html → classPassenger_1_1RuntimeException-members.html} +2 -3
- data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption.html → classPassenger_1_1RuntimeException.html} +10 -8
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -2
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +15 -56
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +5 -4
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +20 -81
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1SystemException.html +9 -10
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/{classboost_1_1this__thread_1_1disable__syscall__interruption-members.html → classPassenger_1_1SystemTime-members.html} +5 -3
- data/doc/cxxapi/classPassenger_1_1SystemTime.html +86 -0
- data/doc/cxxapi/classPassenger_1_1TempFile-members.html +2 -3
- data/doc/cxxapi/classPassenger_1_1TempFile.html +17 -9
- data/doc/cxxapi/definitions_8h-source.html +1 -2
- data/doc/cxxapi/files.html +6 -3
- data/doc/cxxapi/functions.html +98 -35
- data/doc/cxxapi/functions_func.html +60 -32
- data/doc/cxxapi/functions_type.html +1 -2
- data/doc/cxxapi/functions_vars.html +27 -2
- data/doc/cxxapi/graph_legend.html +1 -2
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Configuration.html +3 -4
- data/doc/cxxapi/group__Configuration.png +0 -0
- data/doc/cxxapi/group__Core.html +3 -4
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +4 -2
- data/doc/cxxapi/group__Hooks.html +1 -6
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +259 -36
- data/doc/cxxapi/hierarchy.html +6 -7
- data/doc/cxxapi/inherit__graph__0.map +1 -1
- data/doc/cxxapi/inherit__graph__0.md5 +1 -1
- data/doc/cxxapi/inherit__graph__0.png +0 -0
- data/doc/cxxapi/inherit__graph__1.map +1 -1
- data/doc/cxxapi/inherit__graph__1.md5 +1 -1
- data/doc/cxxapi/inherit__graph__1.png +0 -0
- data/doc/cxxapi/inherit__graph__10.map +1 -1
- data/doc/cxxapi/inherit__graph__10.md5 +1 -1
- data/doc/cxxapi/inherit__graph__10.png +0 -0
- data/doc/cxxapi/inherit__graph__11.map +1 -1
- data/doc/cxxapi/inherit__graph__11.md5 +1 -1
- data/doc/cxxapi/inherit__graph__11.png +0 -0
- data/doc/cxxapi/inherit__graph__12.map +2 -1
- data/doc/cxxapi/inherit__graph__12.md5 +1 -1
- data/doc/cxxapi/inherit__graph__12.png +0 -0
- data/doc/cxxapi/inherit__graph__13.map +1 -1
- data/doc/cxxapi/inherit__graph__13.md5 +1 -1
- data/doc/cxxapi/inherit__graph__13.png +0 -0
- data/doc/cxxapi/inherit__graph__14.map +1 -2
- data/doc/cxxapi/inherit__graph__14.md5 +1 -1
- data/doc/cxxapi/inherit__graph__14.png +0 -0
- data/doc/cxxapi/inherit__graph__15.map +1 -1
- data/doc/cxxapi/inherit__graph__15.md5 +1 -1
- data/doc/cxxapi/inherit__graph__15.png +0 -0
- data/doc/cxxapi/inherit__graph__16.map +1 -1
- data/doc/cxxapi/inherit__graph__16.md5 +1 -1
- data/doc/cxxapi/inherit__graph__16.png +0 -0
- data/doc/cxxapi/inherit__graph__17.png +0 -0
- data/doc/cxxapi/inherit__graph__18.png +0 -0
- data/doc/cxxapi/inherit__graph__19.png +0 -0
- data/doc/cxxapi/inherit__graph__2.map +1 -1
- data/doc/cxxapi/inherit__graph__2.md5 +1 -1
- data/doc/cxxapi/inherit__graph__2.png +0 -0
- data/doc/cxxapi/inherit__graph__20.map +1 -1
- data/doc/cxxapi/inherit__graph__20.md5 +1 -1
- data/doc/cxxapi/inherit__graph__20.png +0 -0
- data/doc/cxxapi/inherit__graph__21.map +1 -1
- data/doc/cxxapi/inherit__graph__21.md5 +1 -1
- data/doc/cxxapi/inherit__graph__21.png +0 -0
- data/doc/cxxapi/inherit__graph__3.map +1 -1
- data/doc/cxxapi/inherit__graph__3.md5 +1 -1
- data/doc/cxxapi/inherit__graph__3.png +0 -0
- data/doc/cxxapi/inherit__graph__4.map +1 -1
- data/doc/cxxapi/inherit__graph__4.md5 +1 -1
- data/doc/cxxapi/inherit__graph__4.png +0 -0
- data/doc/cxxapi/inherit__graph__5.map +2 -1
- data/doc/cxxapi/inherit__graph__5.md5 +1 -1
- data/doc/cxxapi/inherit__graph__5.png +0 -0
- data/doc/cxxapi/inherit__graph__6.map +1 -1
- data/doc/cxxapi/inherit__graph__6.md5 +1 -1
- data/doc/cxxapi/inherit__graph__6.png +0 -0
- data/doc/cxxapi/inherit__graph__7.map +1 -1
- data/doc/cxxapi/inherit__graph__7.md5 +1 -1
- data/doc/cxxapi/inherit__graph__7.png +0 -0
- data/doc/cxxapi/inherit__graph__8.map +1 -1
- data/doc/cxxapi/inherit__graph__8.md5 +1 -1
- data/doc/cxxapi/inherit__graph__8.png +0 -0
- data/doc/cxxapi/inherit__graph__9.map +1 -2
- data/doc/cxxapi/inherit__graph__9.md5 +1 -1
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +30 -31
- data/doc/cxxapi/main.html +1 -2
- data/doc/cxxapi/modules.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString.html +2 -3
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -2
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +2 -3
- data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +49 -0
- data/doc/cxxapi/structPassenger_1_1PoolOptions.html +404 -0
- data/doc/cxxapi/tree.html +18 -20
- data/doc/images/conservative_spawning.png +0 -0
- data/doc/images/conservative_spawning.svg +248 -0
- data/doc/images/smart-lv2.png +0 -0
- data/doc/images/smart-lv2.svg +320 -0
- data/doc/rdoc/classes/ConditionVariable.html +68 -34
- data/doc/rdoc/classes/Exception.html +16 -16
- data/doc/rdoc/classes/GC.html +9 -9
- data/doc/rdoc/classes/IO.html +36 -17
- data/doc/rdoc/classes/PhusionPassenger.html +183 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +511 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer.html +285 -242
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerAlreadyStarted.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerError.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerNotStarted.html +3 -3
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/UnknownMessage.html +3 -3
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +247 -0
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AppInitError.html +36 -19
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/Application.html +81 -96
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/ConsoleTextTemplate.html +18 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/FrameworkInitError.html +20 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/HTMLTemplate.html +18 -18
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/InitializationError.html +9 -9
- data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/MessageChannel.html +93 -92
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/NativeSupport.html +55 -25
- data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +185 -0
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +182 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +424 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +444 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +154 -0
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +408 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/UnknownError.html +13 -13
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +687 -0
- data/doc/rdoc/classes/{Passenger → PhusionPassenger}/VersionNotFound.html +8 -8
- data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
- data/doc/rdoc/classes/PlatformInfo.html +663 -159
- data/doc/rdoc/classes/RakeExtensions.html +4 -4
- data/doc/rdoc/classes/Signal.html +134 -0
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +15 -10
- data/doc/rdoc/files/README.html +5 -7
- data/doc/rdoc/files/ext/{passenger → phusion_passenger}/native_support_c.html +2 -2
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_request_handler_rb.html +7 -9
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +120 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_server_rb.html +7 -10
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +99 -0
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +92 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/application_rb.html +6 -8
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/console_text_template_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/constants_rb.html +4 -5
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/dependencies_rb.html +6 -8
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +116 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/exceptions_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/html_template_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/message_channel_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/platform_info_rb.html +6 -7
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +123 -0
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +117 -0
- data/doc/rdoc/files/lib/{passenger/utils_rb.html → phusion_passenger/railz/application_spawner_rb.html} +24 -17
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +139 -0
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +118 -0
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/simple_benchmarking_rb.html +5 -7
- data/doc/rdoc/files/lib/{passenger → phusion_passenger}/spawn_manager_rb.html +40 -24
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +169 -0
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +120 -0
- data/doc/rdoc/files/lib/rake/extensions_rb.html +3 -4
- data/doc/rdoc/fr_class_index.html +37 -19
- data/doc/rdoc/fr_file_index.html +25 -14
- data/doc/rdoc/fr_method_index.html +145 -74
- data/ext/apache2/Application.h +145 -44
- data/ext/apache2/ApplicationPool.h +27 -29
- data/ext/apache2/ApplicationPoolServer.h +183 -72
- data/ext/apache2/ApplicationPoolServerExecutable.cpp +249 -42
- data/ext/apache2/Bucket.cpp +61 -9
- data/ext/apache2/Bucket.h +15 -8
- data/ext/apache2/CachedFileStat.cpp +114 -0
- data/ext/apache2/CachedFileStat.h +169 -0
- data/ext/apache2/Configuration.cpp +213 -22
- data/ext/apache2/Configuration.h +176 -13
- data/ext/apache2/DirectoryMapper.h +287 -0
- data/ext/apache2/Exceptions.h +30 -12
- data/ext/apache2/FileChecker.h +108 -0
- data/ext/apache2/Hooks.cpp +709 -493
- data/ext/apache2/LICENSE-CNRI.TXT +15 -0
- data/ext/apache2/Logging.h +26 -22
- data/ext/apache2/MessageChannel.h +124 -15
- data/ext/apache2/PoolOptions.h +283 -0
- data/ext/apache2/SpawnManager.h +75 -99
- data/ext/apache2/StandardApplicationPool.h +296 -195
- data/ext/apache2/SystemTime.cpp +28 -0
- data/ext/apache2/SystemTime.h +82 -0
- data/ext/apache2/Utils.cpp +172 -18
- data/ext/apache2/Utils.h +124 -19
- data/ext/boost/cstdint.hpp +4 -2
- data/ext/boost/current_function.hpp +67 -0
- data/ext/boost/detail/sp_counted_base.hpp +4 -4
- data/ext/boost/thread/exceptions.hpp +2 -1
- data/ext/boost/thread/pthread/thread.hpp +11 -3
- data/ext/boost/thread/pthread/thread_data.hpp +2 -1
- data/ext/oxt/backtrace.cpp +172 -0
- data/ext/oxt/backtrace.hpp +135 -0
- data/ext/oxt/detail/backtrace_disabled.hpp +39 -0
- data/ext/oxt/detail/backtrace_enabled.hpp +155 -0
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +82 -0
- data/ext/oxt/detail/spin_lock_portable.hpp +38 -0
- data/ext/oxt/detail/spin_lock_pthreads.hpp +97 -0
- data/ext/oxt/detail/tracable_exception_disabled.hpp +46 -0
- data/ext/oxt/detail/tracable_exception_enabled.hpp +48 -0
- data/ext/oxt/macros.hpp +58 -0
- data/ext/oxt/spin_lock.hpp +55 -0
- data/ext/{apache2/System.cpp → oxt/system_calls.cpp} +87 -52
- data/ext/oxt/system_calls.hpp +234 -0
- data/ext/oxt/thread.cpp +32 -0
- data/ext/oxt/thread.hpp +223 -0
- data/ext/oxt/tracable_exception.cpp +87 -0
- data/ext/oxt/tracable_exception.hpp +35 -0
- data/{lib/passenger/constants.rb → ext/phusion_passenger/extconf.rb} +14 -9
- data/ext/{passenger → phusion_passenger}/native_support.c +33 -6
- data/lib/{passenger → phusion_passenger}/abstract_request_handler.rb +209 -93
- data/lib/{passenger → phusion_passenger}/abstract_server.rb +23 -8
- data/lib/phusion_passenger/abstract_server_collection.rb +301 -0
- data/lib/phusion_passenger/admin_tools.rb +25 -0
- data/lib/phusion_passenger/admin_tools/control_process.rb +107 -0
- data/lib/{passenger → phusion_passenger}/application.rb +13 -16
- data/lib/{passenger → phusion_passenger}/console_text_template.rb +2 -2
- data/{ext/passenger/extconf.rb → lib/phusion_passenger/constants.rb} +5 -5
- data/lib/{passenger → phusion_passenger}/dependencies.rb +38 -32
- data/lib/phusion_passenger/events.rb +45 -0
- data/lib/{passenger → phusion_passenger}/exceptions.rb +12 -5
- data/lib/{passenger → phusion_passenger}/html_template.rb +2 -2
- data/lib/{passenger → phusion_passenger}/message_channel.rb +3 -2
- data/lib/phusion_passenger/platform_info.rb +500 -0
- data/lib/{passenger → phusion_passenger}/rack/application_spawner.rb +29 -22
- data/lib/{passenger → phusion_passenger}/rack/request_handler.rb +14 -9
- data/lib/{passenger → phusion_passenger}/railz/application_spawner.rb +94 -74
- data/lib/{passenger → phusion_passenger}/railz/cgi_fixed.rb +2 -2
- data/lib/{passenger → phusion_passenger}/railz/framework_spawner.rb +86 -98
- data/lib/{passenger → phusion_passenger}/railz/request_handler.rb +6 -6
- data/lib/{passenger → phusion_passenger}/simple_benchmarking.rb +0 -0
- data/lib/{passenger → phusion_passenger}/spawn_manager.rb +136 -128
- data/lib/{passenger → phusion_passenger}/templates/apache2_config_snippets.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
- data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +38 -0
- data/lib/{passenger → phusion_passenger}/templates/app_init_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/database_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/deployment_example.txt.erb +1 -1
- data/lib/{passenger → phusion_passenger}/templates/error_layout.css +0 -0
- data/lib/{passenger → phusion_passenger}/templates/error_layout.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/framework_init_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/general_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/invalid_app_root.html.erb +1 -1
- data/lib/{passenger → phusion_passenger}/templates/load_error.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/no_write_permission_to_passenger_root.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/run_installer_as_root.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/version_not_found.html.erb +0 -0
- data/lib/{passenger → phusion_passenger}/templates/welcome.txt.erb +0 -0
- data/lib/{passenger → phusion_passenger}/utils.rb +210 -44
- data/lib/{passenger → phusion_passenger}/wsgi/application_spawner.rb +18 -15
- data/lib/{passenger → phusion_passenger}/wsgi/request_handler.py +7 -1
- data/man/passenger-memory-stats.8 +1 -1
- data/misc/render_error_pages.rb +1 -1
- data/test/ApplicationPoolServerTest.cpp +0 -28
- data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +4 -0
- data/test/ApplicationPoolTest.cpp +307 -69
- data/test/CachedFileStatTest.cpp +262 -0
- data/test/FileCheckerTest.cpp +79 -0
- data/test/MessageChannelTest.cpp +3 -3
- data/test/PoolOptionsTest.cpp +37 -0
- data/test/SpawnManagerTest.cpp +4 -4
- data/test/StandardApplicationPoolTest.cpp +4 -0
- data/test/SystemTimeTest.cpp +37 -0
- data/test/UtilsTest.cpp +137 -0
- data/test/integration_tests.rb +270 -23
- data/test/oxt/backtrace_test.cpp +128 -0
- data/test/oxt/oxt_test_main.cpp +25 -0
- data/test/oxt/syscall_interruption_test.cpp +50 -0
- data/test/ruby/abstract_request_handler_spec.rb +83 -0
- data/test/ruby/abstract_server_collection_spec.rb +246 -0
- data/test/ruby/application_spec.rb +3 -3
- data/test/ruby/message_channel_spec.rb +2 -2
- data/test/ruby/rack/application_spawner_spec.rb +3 -5
- data/test/ruby/rails/application_spawner_spec.rb +54 -15
- data/test/ruby/rails/framework_spawner_spec.rb +6 -8
- data/test/ruby/rails/minimal_spawner_spec.rb +29 -0
- data/test/ruby/rails/spawner_error_handling_spec.rb +1 -1
- data/test/ruby/rails/spawner_privilege_lowering_spec.rb +3 -3
- data/test/ruby/spawn_manager_spec.rb +23 -12
- data/test/ruby/utils_spec.rb +36 -2
- data/test/ruby/wsgi/application_spawner_spec.rb +47 -0
- data/test/stub/apache2/httpd.conf.erb +3 -5
- data/test/stub/message_channel.rb +2 -2
- data/test/stub/message_channel_2.rb +2 -2
- data/test/stub/message_channel_3.rb +3 -3
- data/test/stub/minimal-railsapp/README +0 -0
- data/test/stub/minimal-railsapp/config/application.rb +0 -0
- data/test/stub/minimal-railsapp/config/environment.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -0
- data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -0
- data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +8 -0
- data/test/stub/rails_apps/foobar/config/environments/development.rb +1 -2
- data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +21 -1
- data/test/stub/rails_apps/mycook/sites/some.site/public/uploads.html +26 -0
- data/test/stub/rails_apps/mycook/sites/some.site/public/welcome/cached.html +26 -0
- data/test/stub/railsapp/app/controllers/application.rb +0 -0
- data/test/stub/railsapp/app/controllers/bar_controller_1.rb +0 -0
- data/test/stub/railsapp/app/controllers/bar_controller_2.rb +1 -1
- data/test/stub/railsapp/app/controllers/foo_controller.rb +4 -0
- data/test/stub/railsapp/app/helpers/application_helper.rb +0 -0
- data/test/stub/railsapp/config/boot.rb +0 -0
- data/test/stub/railsapp/config/database.yml +0 -0
- data/test/stub/railsapp/config/environment.rb +0 -0
- data/test/stub/railsapp/config/environments/development.rb +0 -0
- data/test/stub/railsapp/config/environments/production.rb +0 -0
- data/test/stub/railsapp/config/initializers/inflections.rb +0 -0
- data/test/stub/railsapp/config/initializers/mime_types.rb +0 -0
- data/test/stub/railsapp/config/routes.rb +0 -0
- data/test/stub/railsapp/public/useless.txt +0 -0
- data/test/stub/spawn_server.rb +3 -4
- data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
- data/test/support/apache2_controller.rb +57 -7
- data/test/support/tut.h +15 -0
- data/vendor/README +12 -0
- data/vendor/README_FOR_PACKAGERS +1 -0
- data/vendor/rack-0.9.1/AUTHORS +8 -0
- data/vendor/rack-0.9.1/COPYING +18 -0
- data/vendor/rack-0.9.1/ChangeLog +1423 -0
- data/vendor/rack-0.9.1/KNOWN-ISSUES +18 -0
- data/vendor/rack-0.9.1/README +306 -0
- data/vendor/rack-0.9.1/Rakefile +188 -0
- data/vendor/rack-0.9.1/SPEC +129 -0
- data/vendor/rack-0.9.1/lib/rack.rb +86 -0
- data/vendor/rack-0.9.1/lib/rack/adapter/camping.rb +22 -0
- data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +28 -0
- data/vendor/rack-0.9.1/lib/rack/auth/abstract/request.rb +37 -0
- data/vendor/rack-0.9.1/lib/rack/auth/basic.rb +58 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/md5.rb +124 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/nonce.rb +51 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/params.rb +55 -0
- data/vendor/rack-0.9.1/lib/rack/auth/digest/request.rb +40 -0
- data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +438 -0
- data/vendor/rack-0.9.1/lib/rack/builder.rb +67 -0
- data/vendor/rack-0.9.1/lib/rack/cascade.rb +36 -0
- data/vendor/rack-0.9.1/lib/rack/commonlogger.rb +61 -0
- data/vendor/rack-0.9.1/lib/rack/conditionalget.rb +43 -0
- data/vendor/rack-0.9.1/lib/rack/content_length.rb +25 -0
- data/vendor/rack-0.9.1/lib/rack/deflater.rb +87 -0
- data/vendor/rack-0.9.1/lib/rack/directory.rb +150 -0
- data/vendor/rack-0.9.1/lib/rack/file.rb +85 -0
- data/vendor/rack-0.9.1/lib/rack/handler.rb +48 -0
- data/vendor/rack-0.9.1/lib/rack/handler/cgi.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/handler/evented_mongrel.rb +8 -0
- data/vendor/rack-0.9.1/lib/rack/handler/fastcgi.rb +86 -0
- data/vendor/rack-0.9.1/lib/rack/handler/lsws.rb +52 -0
- data/vendor/rack-0.9.1/lib/rack/handler/mongrel.rb +82 -0
- data/vendor/rack-0.9.1/lib/rack/handler/scgi.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/vendor/rack-0.9.1/lib/rack/handler/thin.rb +15 -0
- data/vendor/rack-0.9.1/lib/rack/handler/webrick.rb +61 -0
- data/vendor/rack-0.9.1/lib/rack/head.rb +19 -0
- data/vendor/rack-0.9.1/lib/rack/lint.rb +465 -0
- data/vendor/rack-0.9.1/lib/rack/lobster.rb +65 -0
- data/vendor/rack-0.9.1/lib/rack/methodoverride.rb +27 -0
- data/vendor/rack-0.9.1/lib/rack/mime.rb +204 -0
- data/vendor/rack-0.9.1/lib/rack/mock.rb +160 -0
- data/vendor/rack-0.9.1/lib/rack/recursive.rb +57 -0
- data/vendor/rack-0.9.1/lib/rack/reloader.rb +64 -0
- data/vendor/rack-0.9.1/lib/rack/request.rb +218 -0
- data/vendor/rack-0.9.1/lib/rack/response.rb +171 -0
- data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +153 -0
- data/vendor/rack-0.9.1/lib/rack/session/cookie.rb +89 -0
- data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +97 -0
- data/vendor/rack-0.9.1/lib/rack/session/pool.rb +73 -0
- data/vendor/rack-0.9.1/lib/rack/showexceptions.rb +348 -0
- data/vendor/rack-0.9.1/lib/rack/showstatus.rb +106 -0
- data/vendor/rack-0.9.1/lib/rack/static.rb +38 -0
- data/vendor/rack-0.9.1/lib/rack/urlmap.rb +48 -0
- data/vendor/rack-0.9.1/lib/rack/utils.rb +347 -0
- metadata +1197 -1055
- data/doc/cxxapi/System_8h-source.html +0 -251
- data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
- data/doc/cxxapi/classDirectoryMapper.html +0 -203
- data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
- data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
- data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
- data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
- data/doc/cxxapi/namespacePassenger.html +0 -208
- data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
- data/doc/cxxapi/namespacemembers.html +0 -70
- data/doc/cxxapi/namespacemembers_func.html +0 -66
- data/doc/cxxapi/namespacemembers_type.html +0 -46
- data/doc/cxxapi/namespaces.html +0 -35
- data/doc/rdoc/classes/Passenger.html +0 -136
- data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -402
- data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -379
- data/doc/rdoc/classes/Passenger/Utils.html +0 -578
- data/ext/apache2/System.h +0 -228
- data/lib/passenger/platform_info.rb +0 -302
- data/lib/passenger/templates/app_exited_during_initialization.html.erb +0 -19
- data/test/stub/apache2/httpd.conf +0 -75
- data/test/stub/rails_apps/foobar/config/environments/test.rb +0 -22
- data/test/stub/rails_apps/mycook/config/environments/test.rb +0 -22
- data/test/stub/railsapp/config/environments/test.rb +0 -22
- data/test/stub/railsapp2/config/environments/test.rb +0 -22
@@ -14,14 +14,17 @@
|
|
14
14
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
15
15
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
16
16
|
|
17
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../../../vendor/rack-0.9.1/lib"))
|
17
18
|
require 'rack'
|
19
|
+
|
18
20
|
require 'socket'
|
19
|
-
require '
|
20
|
-
require '
|
21
|
-
require '
|
22
|
-
require '
|
23
|
-
require '
|
24
|
-
|
21
|
+
require 'phusion_passenger/application'
|
22
|
+
require 'phusion_passenger/message_channel'
|
23
|
+
require 'phusion_passenger/abstract_request_handler'
|
24
|
+
require 'phusion_passenger/utils'
|
25
|
+
require 'phusion_passenger/rack/request_handler'
|
26
|
+
|
27
|
+
module PhusionPassenger
|
25
28
|
module Rack
|
26
29
|
|
27
30
|
# Class for spawning Rack applications.
|
@@ -41,14 +44,18 @@ class ApplicationSpawner
|
|
41
44
|
# - AppInitError: The Rack application raised an exception or called
|
42
45
|
# exit() during startup.
|
43
46
|
# - SystemCallError, IOError, SocketError: Something went wrong.
|
44
|
-
def spawn_application(app_root,
|
47
|
+
def spawn_application(app_root, options = {})
|
48
|
+
options = sanitize_spawn_options(options)
|
49
|
+
|
45
50
|
a, b = UNIXSocket.pair
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
51
|
+
pid = safe_fork(self.class.to_s, true) do
|
52
|
+
a.close
|
53
|
+
|
54
|
+
file_descriptors_to_leave_open = [0, 1, 2, b.fileno]
|
55
|
+
NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open)
|
56
|
+
close_all_io_objects_for_fds(file_descriptors_to_leave_open)
|
57
|
+
|
58
|
+
run(MessageChannel.new(b), app_root, options)
|
52
59
|
end
|
53
60
|
b.close
|
54
61
|
Process.waitpid(pid) rescue nil
|
@@ -57,25 +64,25 @@ class ApplicationSpawner
|
|
57
64
|
unmarshal_and_raise_errors(channel, "rack")
|
58
65
|
|
59
66
|
# No exception was raised, so spawning succeeded.
|
60
|
-
pid, socket_name,
|
67
|
+
pid, socket_name, socket_type = channel.read
|
61
68
|
if pid.nil?
|
62
69
|
raise IOError, "Connection closed"
|
63
70
|
end
|
64
71
|
owner_pipe = channel.recv_io
|
65
72
|
return Application.new(@app_root, pid, socket_name,
|
66
|
-
|
73
|
+
socket_type, owner_pipe)
|
67
74
|
end
|
68
75
|
|
69
76
|
private
|
70
77
|
|
71
|
-
def run(channel, app_root,
|
78
|
+
def run(channel, app_root, options)
|
72
79
|
$0 = "Rack: #{app_root}"
|
73
80
|
app = nil
|
74
81
|
success = report_app_init_status(channel) do
|
75
|
-
ENV['RACK_ENV'] = environment
|
82
|
+
ENV['RACK_ENV'] = options["environment"]
|
76
83
|
Dir.chdir(app_root)
|
77
|
-
if lower_privilege
|
78
|
-
lower_privilege('config.ru', lowest_user)
|
84
|
+
if options["lower_privilege"]
|
85
|
+
lower_privilege('config.ru', options["lowest_user"])
|
79
86
|
end
|
80
87
|
app = load_rack_app
|
81
88
|
end
|
@@ -83,9 +90,9 @@ private
|
|
83
90
|
if success
|
84
91
|
reader, writer = IO.pipe
|
85
92
|
begin
|
86
|
-
handler = RequestHandler.new(reader, app)
|
93
|
+
handler = RequestHandler.new(reader, app, options)
|
87
94
|
channel.write(Process.pid, handler.socket_name,
|
88
|
-
handler.
|
95
|
+
handler.socket_type)
|
89
96
|
channel.send_io(writer)
|
90
97
|
writer.close
|
91
98
|
channel.close
|
@@ -105,4 +112,4 @@ private
|
|
105
112
|
end
|
106
113
|
|
107
114
|
end # module Rack
|
108
|
-
end # module
|
115
|
+
end # module PhusionPassenger
|
@@ -14,8 +14,8 @@
|
|
14
14
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
15
15
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
16
16
|
|
17
|
-
require '
|
18
|
-
module
|
17
|
+
require 'phusion_passenger/abstract_request_handler'
|
18
|
+
module PhusionPassenger
|
19
19
|
module Rack
|
20
20
|
|
21
21
|
# A request handler for Rack applications.
|
@@ -40,8 +40,8 @@ class RequestHandler < AbstractRequestHandler
|
|
40
40
|
CRLF = "\r\n" # :nodoc:
|
41
41
|
|
42
42
|
# +app+ is the Rack application object.
|
43
|
-
def initialize(owner_pipe, app)
|
44
|
-
super(owner_pipe)
|
43
|
+
def initialize(owner_pipe, app, options = {})
|
44
|
+
super(owner_pipe, options)
|
45
45
|
@app = app
|
46
46
|
end
|
47
47
|
|
@@ -66,13 +66,18 @@ protected
|
|
66
66
|
begin
|
67
67
|
output.write("Status: #{status}#{CRLF}")
|
68
68
|
headers[X_POWERED_BY] = PASSENGER_HEADER
|
69
|
-
headers.
|
70
|
-
|
71
|
-
|
69
|
+
headers.each_pair do |key, values|
|
70
|
+
if values.is_a?(String)
|
71
|
+
values = values.split("\n")
|
72
|
+
end
|
73
|
+
values.each do |value|
|
74
|
+
output.write("#{key}: #{value}#{CRLF}")
|
72
75
|
end
|
73
76
|
end
|
74
77
|
output.write(CRLF)
|
75
|
-
if body
|
78
|
+
if body.is_a?(String)
|
79
|
+
output.write(body)
|
80
|
+
elsif body
|
76
81
|
body.each do |s|
|
77
82
|
output.write(s)
|
78
83
|
end
|
@@ -84,4 +89,4 @@ protected
|
|
84
89
|
end
|
85
90
|
|
86
91
|
end # module Rack
|
87
|
-
end # module
|
92
|
+
end # module PhusionPassenger
|
@@ -20,15 +20,17 @@ require 'rubygems'
|
|
20
20
|
require 'socket'
|
21
21
|
require 'etc'
|
22
22
|
require 'fcntl'
|
23
|
-
require '
|
24
|
-
require '
|
25
|
-
require '
|
26
|
-
require '
|
27
|
-
require '
|
28
|
-
require '
|
29
|
-
require '
|
23
|
+
require 'phusion_passenger/application'
|
24
|
+
require 'phusion_passenger/abstract_server'
|
25
|
+
require 'phusion_passenger/application'
|
26
|
+
require 'phusion_passenger/constants'
|
27
|
+
require 'phusion_passenger/events'
|
28
|
+
require 'phusion_passenger/railz/request_handler'
|
29
|
+
require 'phusion_passenger/rack/request_handler'
|
30
|
+
require 'phusion_passenger/exceptions'
|
31
|
+
require 'phusion_passenger/utils'
|
30
32
|
|
31
|
-
module
|
33
|
+
module PhusionPassenger
|
32
34
|
module Railz
|
33
35
|
|
34
36
|
# This class is capable of spawning instances of a single Ruby on Rails application.
|
@@ -53,41 +55,45 @@ class ApplicationSpawner < AbstractServer
|
|
53
55
|
# The group ID of the root user.
|
54
56
|
ROOT_GID = 0
|
55
57
|
|
56
|
-
# An attribute, used internally. This should not be used outside Passenger.
|
57
|
-
attr_accessor :time
|
58
58
|
# The application root of this spawner.
|
59
59
|
attr_reader :app_root
|
60
60
|
|
61
61
|
# +app_root+ is the root directory of this application, i.e. the directory
|
62
62
|
# that contains 'app/', 'public/', etc. If given an invalid directory,
|
63
63
|
# or a directory that doesn't appear to be a Rails application root directory,
|
64
|
-
# then an
|
64
|
+
# then an InvalidPath will be raised.
|
65
65
|
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
66
|
+
# Additional options are:
|
67
|
+
# - +lower_privilege+ and +lowest_user+:
|
68
|
+
# If +lower_privilege+ is true, then ApplicationSpawner will attempt to
|
69
|
+
# switch to the user who owns the application's <tt>config/environment.rb</tt>,
|
70
|
+
# and to the default group of that user.
|
69
71
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
72
|
+
# If that user doesn't exist on the system, or if that user is root,
|
73
|
+
# then ApplicationSpawner will attempt to switch to the username given by
|
74
|
+
# +lowest_user+ (and to the default group of that user).
|
75
|
+
# If +lowest_user+ doesn't exist either, or if switching user failed
|
76
|
+
# (because the current process does not have the privilege to do so),
|
77
|
+
# then ApplicationSpawner will continue without reporting an error.
|
76
78
|
#
|
77
|
-
#
|
78
|
-
|
79
|
+
# - +environment+:
|
80
|
+
# Allows one to specify the RAILS_ENV environment to use.
|
81
|
+
#
|
82
|
+
# All other options will be passed on to RequestHandler.
|
83
|
+
def initialize(app_root, options = {})
|
79
84
|
super()
|
80
85
|
begin
|
81
86
|
@app_root = normalize_path(app_root)
|
82
87
|
rescue SystemCallError => e
|
83
|
-
raise
|
84
|
-
rescue
|
88
|
+
raise InvalidPath, e.message
|
89
|
+
rescue InvalidPath
|
85
90
|
raise
|
86
91
|
end
|
87
|
-
@
|
88
|
-
@
|
89
|
-
@
|
90
|
-
|
92
|
+
@options = sanitize_spawn_options(options)
|
93
|
+
@lower_privilege = @options["lower_privilege"]
|
94
|
+
@lowest_user = @options["lowest_user"]
|
95
|
+
@environment = @options["environment"]
|
96
|
+
self.max_idle_time = DEFAULT_APP_SPAWNER_MAX_IDLE_TIME
|
91
97
|
assert_valid_app_root(@app_root)
|
92
98
|
define_message_handler(:spawn_application, :handle_spawn_application)
|
93
99
|
end
|
@@ -100,15 +106,15 @@ class ApplicationSpawner < AbstractServer
|
|
100
106
|
# - ApplicationSpawner::Error: The ApplicationSpawner server exited unexpectedly.
|
101
107
|
def spawn_application
|
102
108
|
server.write("spawn_application")
|
103
|
-
pid, socket_name,
|
109
|
+
pid, socket_name, socket_type = server.read
|
104
110
|
if pid.nil?
|
105
111
|
raise IOError, "Connection closed"
|
106
112
|
end
|
107
113
|
owner_pipe = server.recv_io
|
108
114
|
return Application.new(@app_root, pid, socket_name,
|
109
|
-
|
115
|
+
socket_type, owner_pipe)
|
110
116
|
rescue SystemCallError, IOError, SocketError => e
|
111
|
-
raise Error, "The application spawner server exited unexpectedly"
|
117
|
+
raise Error, "The application spawner server exited unexpectedly: #{e}"
|
112
118
|
end
|
113
119
|
|
114
120
|
# Spawn an instance of the RoR application. When successful, an Application object
|
@@ -126,30 +132,37 @@ class ApplicationSpawner < AbstractServer
|
|
126
132
|
# or called exit() during startup.
|
127
133
|
# - SystemCallError, IOError, SocketError: Something went wrong.
|
128
134
|
def spawn_application!
|
129
|
-
# Double fork to prevent zombie processes.
|
130
135
|
a, b = UNIXSocket.pair
|
131
|
-
pid = safe_fork(
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
if success
|
146
|
-
start_request_handler(channel)
|
147
|
-
end
|
148
|
-
rescue SignalException => e
|
149
|
-
if e.message != AbstractRequestHandler::HARD_TERMINATION_SIGNAL &&
|
150
|
-
e.message != AbstractRequestHandler::SOFT_TERMINATION_SIGNAL
|
151
|
-
raise
|
136
|
+
pid = safe_fork('application', true) do
|
137
|
+
begin
|
138
|
+
a.close
|
139
|
+
|
140
|
+
file_descriptors_to_leave_open = [0, 1, 2, b.fileno]
|
141
|
+
NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open)
|
142
|
+
close_all_io_objects_for_fds(file_descriptors_to_leave_open)
|
143
|
+
|
144
|
+
channel = MessageChannel.new(b)
|
145
|
+
success = report_app_init_status(channel) do
|
146
|
+
ENV['RAILS_ENV'] = @environment
|
147
|
+
Dir.chdir(@app_root)
|
148
|
+
if @lower_privilege
|
149
|
+
lower_privilege('config/environment.rb', @lowest_user)
|
152
150
|
end
|
151
|
+
|
152
|
+
# require Rails' environment, using the same path as the original rails dispatcher,
|
153
|
+
# which normally does: require File.dirname(__FILE__) + "/../config/environment"
|
154
|
+
# thus avoiding the possibility of including the same file twice.
|
155
|
+
require 'public/../config/environment'
|
156
|
+
|
157
|
+
require 'dispatcher'
|
158
|
+
end
|
159
|
+
if success
|
160
|
+
start_request_handler(channel, false)
|
161
|
+
end
|
162
|
+
rescue SignalException => e
|
163
|
+
if e.message != AbstractRequestHandler::HARD_TERMINATION_SIGNAL &&
|
164
|
+
e.message != AbstractRequestHandler::SOFT_TERMINATION_SIGNAL
|
165
|
+
raise
|
153
166
|
end
|
154
167
|
end
|
155
168
|
end
|
@@ -160,13 +173,13 @@ class ApplicationSpawner < AbstractServer
|
|
160
173
|
unmarshal_and_raise_errors(channel)
|
161
174
|
|
162
175
|
# No exception was raised, so spawning succeeded.
|
163
|
-
pid, socket_name,
|
176
|
+
pid, socket_name, socket_type = channel.read
|
164
177
|
if pid.nil?
|
165
178
|
raise IOError, "Connection closed"
|
166
179
|
end
|
167
180
|
owner_pipe = channel.recv_io
|
168
181
|
return Application.new(@app_root, pid, socket_name,
|
169
|
-
|
182
|
+
socket_type, owner_pipe)
|
170
183
|
end
|
171
184
|
|
172
185
|
# Overrided from AbstractServer#start.
|
@@ -179,9 +192,9 @@ class ApplicationSpawner < AbstractServer
|
|
179
192
|
super
|
180
193
|
begin
|
181
194
|
unmarshal_and_raise_errors(server)
|
182
|
-
rescue IOError, SystemCallError, SocketError
|
195
|
+
rescue IOError, SystemCallError, SocketError => e
|
183
196
|
stop
|
184
|
-
raise Error, "The application spawner server exited unexpectedly"
|
197
|
+
raise Error, "The application spawner server exited unexpectedly: #{e}"
|
185
198
|
rescue
|
186
199
|
stop
|
187
200
|
raise
|
@@ -267,7 +280,12 @@ private
|
|
267
280
|
else
|
268
281
|
require_dependency 'application'
|
269
282
|
end
|
270
|
-
|
283
|
+
|
284
|
+
# - No point in preloading the application sources if the garbage collector
|
285
|
+
# isn't copy-on-write friendly.
|
286
|
+
# - Rails >= 2.2 already preloads application sources by default, so no need
|
287
|
+
# to do that again.
|
288
|
+
if GC.copy_on_write_friendly? && !::Rails::Initializer.respond_to?(:load_application_classes)
|
271
289
|
Dir.glob('app/{models,controllers,helpers}/*.rb').each do |file|
|
272
290
|
require_dependency normalize_path(file)
|
273
291
|
end
|
@@ -275,25 +293,24 @@ private
|
|
275
293
|
end
|
276
294
|
|
277
295
|
def handle_spawn_application
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
e.message != AbstractRequestHandler::SOFT_TERMINATION_SIGNAL
|
286
|
-
raise
|
287
|
-
end
|
296
|
+
safe_fork('application', true) do
|
297
|
+
begin
|
298
|
+
start_request_handler(client, true)
|
299
|
+
rescue SignalException => e
|
300
|
+
if e.message != AbstractRequestHandler::HARD_TERMINATION_SIGNAL &&
|
301
|
+
e.message != AbstractRequestHandler::SOFT_TERMINATION_SIGNAL
|
302
|
+
raise
|
288
303
|
end
|
289
304
|
end
|
290
305
|
end
|
291
|
-
Process.waitpid(pid)
|
292
306
|
end
|
293
307
|
|
294
308
|
# Initialize the request handler and enter its main loop.
|
295
309
|
# Spawn information will be sent back via _channel_.
|
296
|
-
|
310
|
+
# The _forked_ argument indicates whether a new process was forked off
|
311
|
+
# after loading environment.rb (i.e. whether smart spawning is being
|
312
|
+
# used).
|
313
|
+
def start_request_handler(channel, forked)
|
297
314
|
$0 = "Rails: #{@app_root}"
|
298
315
|
reader, writer = IO.pipe
|
299
316
|
begin
|
@@ -308,24 +325,27 @@ private
|
|
308
325
|
|
309
326
|
if Rails::VERSION::STRING >= '2.3.0'
|
310
327
|
rack_app = ::ActionController::Dispatcher.new
|
311
|
-
handler = Rack::RequestHandler.new(reader, rack_app)
|
328
|
+
handler = Rack::RequestHandler.new(reader, rack_app, @options)
|
312
329
|
else
|
313
|
-
handler = RequestHandler.new(reader)
|
330
|
+
handler = RequestHandler.new(reader, @options)
|
314
331
|
end
|
315
332
|
|
316
333
|
channel.write(Process.pid, handler.socket_name,
|
317
|
-
handler.
|
334
|
+
handler.socket_type)
|
318
335
|
channel.send_io(writer)
|
319
336
|
writer.close
|
320
337
|
channel.close
|
338
|
+
|
339
|
+
PhusionPassenger.call_event(:starting_worker_process, forked)
|
321
340
|
handler.main_loop
|
322
341
|
ensure
|
323
342
|
channel.close rescue nil
|
324
343
|
writer.close rescue nil
|
325
344
|
handler.cleanup rescue nil
|
345
|
+
PhusionPassenger.call_event(:stopping_worker_process)
|
326
346
|
end
|
327
347
|
end
|
328
348
|
end
|
329
349
|
|
330
350
|
end # module Railz
|
331
|
-
end # module
|
351
|
+
end # module PhusionPassenger
|
@@ -26,7 +26,7 @@
|
|
26
26
|
|
27
27
|
require 'cgi'
|
28
28
|
|
29
|
-
module
|
29
|
+
module PhusionPassenger
|
30
30
|
module Railz
|
31
31
|
|
32
32
|
# Modifies CGI so that we can use it. Main thing it does is expose
|
@@ -65,4 +65,4 @@ class CGIFixed < ::CGI
|
|
65
65
|
end
|
66
66
|
|
67
67
|
end # module Railz
|
68
|
-
end # module
|
68
|
+
end # module PhusionPassenger
|
@@ -17,12 +17,13 @@
|
|
17
17
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
18
18
|
|
19
19
|
require 'rubygems'
|
20
|
-
require '
|
21
|
-
require '
|
22
|
-
require '
|
23
|
-
require '
|
24
|
-
require '
|
25
|
-
|
20
|
+
require 'phusion_passenger/abstract_server'
|
21
|
+
require 'phusion_passenger/abstract_server_collection'
|
22
|
+
require 'phusion_passenger/railz/application_spawner'
|
23
|
+
require 'phusion_passenger/exceptions'
|
24
|
+
require 'phusion_passenger/constants'
|
25
|
+
require 'phusion_passenger/utils'
|
26
|
+
module PhusionPassenger
|
26
27
|
module Railz
|
27
28
|
|
28
29
|
# This class is capable of spawning Ruby on Rails application instances
|
@@ -45,12 +46,9 @@ class FrameworkSpawner < AbstractServer
|
|
45
46
|
class Error < AbstractServer::ServerError
|
46
47
|
end
|
47
48
|
|
48
|
-
# An attribute, used internally. This should not be used outside Passenger.
|
49
|
-
attr_accessor :time
|
50
|
-
|
51
49
|
# Creates a new instance of FrameworkSpawner.
|
52
50
|
#
|
53
|
-
# Valid options:
|
51
|
+
# Valid options are:
|
54
52
|
# - <tt>:version</tt>: The Ruby on Rails version to use. It is not checked whether
|
55
53
|
# this version is actually installed.
|
56
54
|
# - <tt>:vendor</tt>: The directory to the vendor Rails framework to use. This is
|
@@ -58,6 +56,8 @@ class FrameworkSpawner < AbstractServer
|
|
58
56
|
#
|
59
57
|
# It is not allowed to specify both +version+ and +vendor+.
|
60
58
|
#
|
59
|
+
# All other options will be passed on to ApplicationSpawner and RequestHandler.
|
60
|
+
#
|
61
61
|
# Note that the specified Rails framework will be loaded during the entire life time
|
62
62
|
# of the FrameworkSpawner server. If you wish to reload the Rails framework's code,
|
63
63
|
# then restart the server by calling AbstractServer#stop and AbstractServer#start.
|
@@ -66,7 +66,7 @@ class FrameworkSpawner < AbstractServer
|
|
66
66
|
raise ArgumentError, "The 'options' argument not seem to be an options hash"
|
67
67
|
end
|
68
68
|
@version = options[:version]
|
69
|
-
@vendor
|
69
|
+
@vendor = options[:vendor]
|
70
70
|
if !@version && !@vendor
|
71
71
|
raise ArgumentError, "Either the 'version' or the 'vendor' option must specified"
|
72
72
|
elsif @version && @vendor
|
@@ -74,6 +74,7 @@ class FrameworkSpawner < AbstractServer
|
|
74
74
|
end
|
75
75
|
|
76
76
|
super()
|
77
|
+
self.max_idle_time = DEFAULT_FRAMEWORK_SPAWNER_MAX_IDLE_TIME
|
77
78
|
define_message_handler(:spawn_application, :handle_spawn_application)
|
78
79
|
define_message_handler(:reload, :handle_reload)
|
79
80
|
end
|
@@ -86,7 +87,12 @@ class FrameworkSpawner < AbstractServer
|
|
86
87
|
def start
|
87
88
|
super
|
88
89
|
begin
|
89
|
-
|
90
|
+
result = server.read
|
91
|
+
if result.nil?
|
92
|
+
raise Error, "The framework spawner server exited unexpectedly."
|
93
|
+
else
|
94
|
+
status = result[0]
|
95
|
+
end
|
90
96
|
if status == 'exception'
|
91
97
|
child_exception = unmarshal_exception(server.read_scalar)
|
92
98
|
stop
|
@@ -111,8 +117,23 @@ class FrameworkSpawner < AbstractServer
|
|
111
117
|
# When successful, an Application object will be returned, which represents
|
112
118
|
# the spawned RoR application.
|
113
119
|
#
|
114
|
-
#
|
115
|
-
# +
|
120
|
+
# The following options are allowed:
|
121
|
+
# - +lower_privilege+ and +lowest_user+:
|
122
|
+
# If +lower_privilege+ is true, then ApplicationSpawner will attempt to
|
123
|
+
# switch to the user who owns the application's <tt>config/environment.rb</tt>,
|
124
|
+
# and to the default group of that user.
|
125
|
+
#
|
126
|
+
# If that user doesn't exist on the system, or if that user is root,
|
127
|
+
# then ApplicationSpawner will attempt to switch to the username given by
|
128
|
+
# +lowest_user+ (and to the default group of that user).
|
129
|
+
# If +lowest_user+ doesn't exist either, or if switching user failed
|
130
|
+
# (because the current process does not have the privilege to do so),
|
131
|
+
# then ApplicationSpawner will continue without reporting an error.
|
132
|
+
#
|
133
|
+
# - +environment+:
|
134
|
+
# Allows one to specify the RAILS_ENV environment to use.
|
135
|
+
#
|
136
|
+
# All other options will be passed on to ApplicationSpawner and RequestHandler.
|
116
137
|
#
|
117
138
|
# FrameworkSpawner will internally cache the code of applications, in order to
|
118
139
|
# speed up future spawning attempts. This implies that, if you've changed
|
@@ -122,30 +143,37 @@ class FrameworkSpawner < AbstractServer
|
|
122
143
|
#
|
123
144
|
# Raises:
|
124
145
|
# - AbstractServer::ServerNotStarted: The FrameworkSpawner server hasn't already been started.
|
125
|
-
# -
|
146
|
+
# - InvalidAppRoot: +app_root+ doesn't appear to be a valid Ruby on Rails application root.
|
126
147
|
# - AppInitError: The application raised an exception or called exit() during startup.
|
127
148
|
# - ApplicationSpawner::Error: The ApplicationSpawner server exited unexpectedly.
|
128
149
|
# - FrameworkSpawner::Error: The FrameworkSpawner server exited unexpectedly.
|
129
|
-
def spawn_application(app_root,
|
150
|
+
def spawn_application(app_root, options = {})
|
130
151
|
app_root = normalize_path(app_root)
|
131
152
|
assert_valid_app_root(app_root)
|
153
|
+
options = sanitize_spawn_options(options)
|
154
|
+
options["app_root"] = app_root
|
155
|
+
|
132
156
|
exception_to_propagate = nil
|
133
157
|
begin
|
134
|
-
server.write("spawn_application",
|
158
|
+
server.write("spawn_application", *options.to_a.flatten)
|
135
159
|
result = server.read
|
136
160
|
if result.nil?
|
137
161
|
raise IOError, "Connection closed"
|
138
162
|
end
|
139
163
|
if result[0] == 'exception'
|
140
|
-
|
164
|
+
e = unmarshal_exception(server.read_scalar)
|
165
|
+
if e.respond_to?(:child_exception) && e.child_exception
|
166
|
+
#print_exception(self.class.to_s, e.child_exception)
|
167
|
+
end
|
168
|
+
raise e
|
141
169
|
else
|
142
|
-
pid, listen_socket_name,
|
170
|
+
pid, listen_socket_name, socket_type = server.read
|
143
171
|
if pid.nil?
|
144
172
|
raise IOError, "Connection closed"
|
145
173
|
end
|
146
174
|
owner_pipe = server.recv_io
|
147
175
|
return Application.new(app_root, pid, listen_socket_name,
|
148
|
-
|
176
|
+
socket_type, owner_pipe)
|
149
177
|
end
|
150
178
|
rescue SystemCallError, IOError, SocketError => e
|
151
179
|
raise Error, "The framework spawner server exited unexpectedly"
|
@@ -191,16 +219,7 @@ protected
|
|
191
219
|
# Overrided method.
|
192
220
|
def initialize_server # :nodoc:
|
193
221
|
$0 = "Passenger FrameworkSpawner: #{@version || @vendor}"
|
194
|
-
@spawners =
|
195
|
-
@spawners_lock = Mutex.new
|
196
|
-
@spawners_cond = ConditionVariable.new
|
197
|
-
@spawners_cleaner = Thread.new do
|
198
|
-
begin
|
199
|
-
spawners_cleaner_main_loop
|
200
|
-
rescue Exception => e
|
201
|
-
print_exception(self.class.to_s, e)
|
202
|
-
end
|
203
|
-
end
|
222
|
+
@spawners = AbstractServerCollection.new
|
204
223
|
begin
|
205
224
|
preload_rails
|
206
225
|
rescue StandardError, ScriptError, NoMemoryError => e
|
@@ -213,13 +232,7 @@ protected
|
|
213
232
|
|
214
233
|
# Overrided method.
|
215
234
|
def finalize_server # :nodoc:
|
216
|
-
@
|
217
|
-
@spawners_cond.signal
|
218
|
-
end
|
219
|
-
@spawners_cleaner.join
|
220
|
-
@spawners.each_value do |spawner|
|
221
|
-
spawner.stop
|
222
|
-
end
|
235
|
+
@spawners.cleanup
|
223
236
|
end
|
224
237
|
|
225
238
|
private
|
@@ -258,31 +271,36 @@ private
|
|
258
271
|
Object.send(:remove_const, :RAILS_ROOT)
|
259
272
|
end
|
260
273
|
|
261
|
-
def handle_spawn_application(
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
# A source file failed to load, maybe because of a
|
276
|
-
# missing gem. If that's the case then the sysadmin
|
277
|
-
# will install probably the gem. So we clear RubyGems's
|
278
|
-
# cache so that it can detect new gems.
|
279
|
-
Gem.clear_paths
|
274
|
+
def handle_spawn_application(*options)
|
275
|
+
options = Hash[*options]
|
276
|
+
options["lower_privilege"] = options["lower_privilege"] == "true"
|
277
|
+
options["app_spawner_timeout"] = options["app_spawner_timeout"].to_i
|
278
|
+
options["memory_limit"] = options["memory_limit"].to_i
|
279
|
+
|
280
|
+
app = nil
|
281
|
+
app_root = options["app_root"]
|
282
|
+
@spawners.synchronize do
|
283
|
+
begin
|
284
|
+
spawner = @spawners.lookup_or_add(app_root) do
|
285
|
+
spawner = ApplicationSpawner.new(app_root, options)
|
286
|
+
if options["app_spawner_timeout"] && options["app_spawner_timeout"] != -1
|
287
|
+
spawner.max_idle_time = options["app_spawner_timeout"]
|
280
288
|
end
|
281
|
-
|
289
|
+
spawner.start
|
290
|
+
spawner
|
282
291
|
end
|
283
|
-
|
292
|
+
rescue ArgumentError, AppInitError, ApplicationSpawner::Error => e
|
293
|
+
client.write('exception')
|
294
|
+
client.write_scalar(marshal_exception(e))
|
295
|
+
if e.child_exception.is_a?(LoadError)
|
296
|
+
# A source file failed to load, maybe because of a
|
297
|
+
# missing gem. If that's the case then the sysadmin
|
298
|
+
# will install probably the gem. So we clear RubyGems's
|
299
|
+
# cache so that it can detect new gems.
|
300
|
+
Gem.clear_paths
|
301
|
+
end
|
302
|
+
return
|
284
303
|
end
|
285
|
-
spawner.time = Time.now
|
286
304
|
begin
|
287
305
|
app = spawner.spawn_application
|
288
306
|
rescue ApplicationSpawner::Error => e
|
@@ -292,53 +310,23 @@ private
|
|
292
310
|
client.write_scalar(marshal_exception(e))
|
293
311
|
return
|
294
312
|
end
|
295
|
-
client.write('success')
|
296
|
-
client.write(app.pid, app.listen_socket_name, app.using_abstract_namespace?)
|
297
|
-
client.send_io(app.owner_pipe)
|
298
|
-
app.close
|
299
313
|
end
|
314
|
+
client.write('success')
|
315
|
+
client.write(app.pid, app.listen_socket_name, app.listen_socket_type)
|
316
|
+
client.send_io(app.owner_pipe)
|
317
|
+
app.close
|
300
318
|
end
|
301
319
|
|
302
320
|
def handle_reload(app_root = nil)
|
303
|
-
@
|
304
|
-
if app_root
|
305
|
-
@spawners.
|
306
|
-
spawner.stop
|
307
|
-
end
|
308
|
-
@spawners.clear
|
321
|
+
@spawners.synchronize do
|
322
|
+
if app_root
|
323
|
+
@spawners.delete(app_root)
|
309
324
|
else
|
310
|
-
|
311
|
-
if spawner
|
312
|
-
spawner.stop
|
313
|
-
@spawners.delete(app_root)
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
# The main loop for the spawners cleaner thread.
|
320
|
-
# This thread checks the spawners list every APP_SPAWNER_CLEAN_INTERVAL seconds,
|
321
|
-
# and stops application spawners that have been idle for more than
|
322
|
-
# APP_SPAWNER_MAX_IDLE_TIME seconds.
|
323
|
-
def spawners_cleaner_main_loop
|
324
|
-
@spawners_lock.synchronize do
|
325
|
-
while true
|
326
|
-
if @spawners_cond.timed_wait(@spawners_lock, APP_SPAWNER_CLEAN_INTERVAL)
|
327
|
-
break
|
328
|
-
else
|
329
|
-
current_time = Time.now
|
330
|
-
@spawners.keys.each do |key|
|
331
|
-
spawner = @spawners[key]
|
332
|
-
if current_time - spawner.time > APP_SPAWNER_MAX_IDLE_TIME
|
333
|
-
spawner.stop
|
334
|
-
@spawners.delete(key)
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
325
|
+
@spawners.clear
|
338
326
|
end
|
339
327
|
end
|
340
328
|
end
|
341
329
|
end
|
342
330
|
|
343
331
|
end # module Railz
|
344
|
-
end # module
|
332
|
+
end # module PhusionPassenger
|