passenger 2.1.3 → 2.2.0
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 +2 -0
- data/INSTALL +3 -1
- data/LICENSE +19 -355
- data/NEWS +3 -0
- data/README +11 -4
- data/Rakefile +435 -236
- data/bin/passenger-config +20 -14
- data/bin/passenger-install-apache2-module +67 -201
- data/bin/passenger-install-nginx-module +477 -0
- data/bin/passenger-make-enterprisey +17 -12
- data/bin/passenger-memory-stats +33 -23
- data/bin/passenger-spawn-server +17 -12
- data/bin/passenger-status +18 -13
- data/bin/passenger-stress-test +17 -12
- data/doc/{Users guide.html → Users guide Apache.html } +79 -61
- data/doc/{Users guide.txt → Users guide Apache.txt } +43 -939
- data/doc/Users guide Nginx.html +2276 -0
- data/doc/Users guide Nginx.txt +776 -0
- data/doc/cxxapi/ApplicationPoolServer_8h-source.html +9 -4
- data/doc/cxxapi/ApplicationPool_8h-source.html +9 -4
- data/doc/cxxapi/Application_8h-source.html +26 -21
- data/doc/cxxapi/Bucket_8h-source.html +54 -44
- data/doc/cxxapi/CachedFileStat_8h-source.html +9 -4
- data/doc/cxxapi/Configuration_8h-source.html +357 -339
- data/doc/cxxapi/DirectoryMapper_8h-source.html +294 -280
- data/doc/cxxapi/DummySpawnManager_8h-source.html +9 -4
- data/doc/cxxapi/Exceptions_8h-source.html +9 -4
- data/doc/cxxapi/FileChecker_8h-source.html +9 -4
- data/doc/cxxapi/Hooks_8h-source.html +50 -40
- data/doc/cxxapi/Logging_8h-source.html +9 -4
- data/doc/cxxapi/MessageChannel_8h-source.html +20 -15
- data/doc/cxxapi/PoolOptions_8h-source.html +10 -5
- data/doc/cxxapi/SpawnManager_8h-source.html +9 -4
- data/doc/cxxapi/StandardApplicationPool_8h-source.html +10 -5
- data/doc/cxxapi/SystemTime_8h-source.html +9 -4
- data/doc/cxxapi/Utils_8h-source.html +242 -214
- data/doc/cxxapi/annotated.html +4 -28
- data/doc/cxxapi/classClient-members.html +4 -4
- data/doc/cxxapi/classClient.html +14 -11
- data/doc/cxxapi/classHooks-members.html +4 -5
- data/doc/cxxapi/classHooks.html +26 -24
- data/doc/cxxapi/classPassenger_1_1Application-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1Application.html +40 -37
- data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +95 -92
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +26 -23
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +17 -17
- data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +139 -136
- data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +13 -10
- data/doc/cxxapi/classPassenger_1_1BusyException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1BusyException.html +11 -8
- data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +11 -8
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +4 -5
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +45 -43
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +13 -10
- data/doc/cxxapi/classPassenger_1_1FileChecker-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1FileChecker.html +22 -19
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +12 -9
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1FileSystemException.html +14 -11
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1IOException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1IOException.html +12 -9
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1MessageChannel.html +228 -225
- data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1RuntimeException.html +11 -8
- data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SpawnException.html +14 -11
- data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SpawnManager.html +50 -47
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +73 -70
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1SystemException-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SystemException.html +17 -14
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.map +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.md5 +1 -1
- data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
- data/doc/cxxapi/classPassenger_1_1SystemTime-members.html +4 -4
- data/doc/cxxapi/classPassenger_1_1SystemTime.html +14 -11
- data/doc/cxxapi/classes.html +35 -0
- data/doc/cxxapi/definitions_8h-source.html +9 -4
- data/doc/cxxapi/doxygen.css +311 -303
- data/doc/cxxapi/files.html +9 -18
- data/doc/cxxapi/functions.html +5 -224
- data/doc/cxxapi/functions_func.html +5 -185
- data/doc/cxxapi/functions_type.html +4 -4
- data/doc/cxxapi/functions_vars.html +4 -4
- data/doc/cxxapi/graph_legend.dot +19 -19
- data/doc/cxxapi/graph_legend.html +5 -5
- data/doc/cxxapi/graph_legend.png +0 -0
- data/doc/cxxapi/group__Configuration.html +11 -13
- data/doc/cxxapi/group__Configuration.png +0 -0
- data/doc/cxxapi/group__Core.html +10 -12
- data/doc/cxxapi/group__Core.png +0 -0
- data/doc/cxxapi/group__Exceptions.html +5 -7
- data/doc/cxxapi/group__Hooks.html +5 -7
- data/doc/cxxapi/group__Hooks.png +0 -0
- data/doc/cxxapi/group__Support.html +5 -624
- data/doc/cxxapi/hierarchy.html +6 -6
- 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 +1 -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 -2
- 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 +2 -1
- 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.map +1 -1
- data/doc/cxxapi/inherit__graph__17.md5 +1 -1
- data/doc/cxxapi/inherit__graph__17.png +0 -0
- data/doc/cxxapi/inherit__graph__18.map +1 -1
- data/doc/cxxapi/inherit__graph__18.md5 +1 -1
- data/doc/cxxapi/inherit__graph__18.png +0 -0
- data/doc/cxxapi/inherit__graph__19.map +1 -1
- data/doc/cxxapi/inherit__graph__19.md5 +1 -1
- 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 +2 -2
- 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 +1 -2
- 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 +2 -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 -1
- data/doc/cxxapi/inherit__graph__9.md5 +1 -1
- data/doc/cxxapi/inherit__graph__9.png +0 -0
- data/doc/cxxapi/inherits.html +41 -41
- data/doc/cxxapi/main.html +4 -4
- data/doc/cxxapi/modules.html +4 -5
- data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +4 -4
- data/doc/cxxapi/structPassenger_1_1AnythingToString.html +13 -10
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +5 -5
- data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +16 -13
- data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +4 -4
- data/doc/cxxapi/structPassenger_1_1PoolOptions.html +63 -60
- data/doc/cxxapi/tabs.css +5 -2
- data/doc/cxxapi/tree.html +7 -81
- data/doc/rdoc/classes/ConditionVariable.html +59 -59
- data/doc/rdoc/classes/Exception.html +11 -11
- data/doc/rdoc/classes/GC.html +4 -4
- data/doc/rdoc/classes/IO.html +14 -14
- data/doc/rdoc/classes/PhusionPassenger.html +75 -20
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +153 -0
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +125 -130
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +236 -236
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +213 -213
- data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +28 -28
- data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +91 -75
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +10 -10
- data/doc/rdoc/classes/PhusionPassenger/Application.html +64 -64
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +34 -34
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +13 -13
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +30 -30
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +10 -10
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +136 -136
- data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +24 -24
- data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +42 -42
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +55 -53
- data/doc/rdoc/classes/PhusionPassenger/Railz.html +1 -1
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +25 -30
- data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +23 -23
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +116 -117
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +22 -22
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +118 -124
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +10 -10
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +354 -354
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +9 -9
- data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +37 -37
- data/doc/rdoc/classes/PlatformInfo.html +282 -261
- data/doc/rdoc/classes/RakeExtensions.html +7 -7
- data/doc/rdoc/classes/Signal.html +26 -26
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/DEVELOPERS_TXT.html +6 -1
- data/doc/rdoc/files/README.html +15 -6
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +129 -0
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +20 -13
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +31 -1
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +31 -1
- data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +21 -12
- data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +22 -12
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +21 -12
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +21 -12
- data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +19 -13
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +27 -21
- data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +21 -12
- data/doc/rdoc/files/misc/rake/extensions_rb.html +21 -12
- data/doc/rdoc/fr_class_index.html +1 -0
- data/doc/rdoc/fr_file_index.html +2 -0
- data/doc/rdoc/fr_method_index.html +116 -112
- data/doc/users_guide_snippets/analysis_and_system_maintenance_tools.txt +144 -0
- data/doc/users_guide_snippets/appendix_a_about.txt +13 -0
- data/doc/users_guide_snippets/appendix_b_terminology.txt +63 -0
- data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +304 -0
- data/doc/users_guide_snippets/global_queueing_explained.txt +78 -0
- data/doc/users_guide_snippets/rackup_specifications.txt +75 -0
- data/doc/users_guide_snippets/rails_spawn_method.txt +48 -0
- data/doc/users_guide_snippets/tips.txt +173 -0
- data/ext/apache2/Bucket.cpp +17 -12
- data/ext/apache2/Bucket.h +17 -12
- data/ext/apache2/Configuration.cpp +17 -12
- data/ext/apache2/Configuration.h +27 -14
- data/ext/apache2/DirectoryMapper.h +21 -12
- data/ext/apache2/Hooks.cpp +67 -21
- data/ext/apache2/Hooks.h +17 -12
- data/ext/apache2/mod_passenger.c +17 -12
- data/ext/{apache2 → common}/Application.h +19 -14
- data/ext/{apache2 → common}/ApplicationPool.h +17 -12
- data/ext/{apache2 → common}/ApplicationPoolServer.h +18 -72
- data/ext/{apache2 → common}/ApplicationPoolServerExecutable.cpp +45 -104
- data/ext/common/ApplicationPoolStatusReporter.h +212 -0
- data/ext/{apache2 → common}/CachedFileStat.cpp +17 -12
- data/ext/{apache2 → common}/CachedFileStat.h +17 -12
- data/ext/{apache2 → common}/DummySpawnManager.h +17 -12
- data/ext/{apache2 → common}/Exceptions.h +17 -12
- data/ext/{apache2 → common}/FileChecker.h +17 -12
- data/ext/common/Logging.cpp +65 -0
- data/ext/{apache2 → common}/Logging.h +17 -12
- data/ext/{apache2 → common}/MessageChannel.h +17 -12
- data/ext/{apache2 → common}/PoolOptions.h +17 -12
- data/ext/{apache2 → common}/SpawnManager.h +17 -12
- data/ext/{apache2 → common}/StandardApplicationPool.h +17 -12
- data/ext/common/StaticString.h +147 -0
- data/ext/common/SystemTime.cpp +33 -0
- data/ext/{apache2 → common}/SystemTime.h +17 -12
- data/ext/{apache2 → common}/Utils.cpp +69 -12
- data/ext/{apache2 → common}/Utils.h +41 -12
- data/ext/nginx/Configuration.c +1091 -0
- data/ext/nginx/Configuration.h +71 -0
- data/ext/nginx/ContentHandler.c +1154 -0
- data/ext/nginx/ContentHandler.h +64 -0
- data/ext/nginx/HelperServer.cpp +857 -0
- data/ext/nginx/HttpStatusExtractor.h +161 -0
- data/ext/nginx/ScgiRequestParser.h +317 -0
- data/ext/nginx/StaticContentHandler.c +222 -0
- data/ext/nginx/StaticContentHandler.h +37 -0
- data/ext/nginx/config +41 -0
- data/ext/nginx/ngx_http_passenger_module.c +572 -0
- data/ext/nginx/ngx_http_passenger_module.h +72 -0
- data/ext/oxt/backtrace.cpp +8 -1
- data/ext/oxt/system_calls.cpp +40 -0
- data/ext/oxt/system_calls.hpp +14 -7
- data/ext/phusion_passenger/extconf.rb +17 -12
- data/ext/phusion_passenger/native_support.c +19 -12
- data/lib/phusion_passenger/abstract_installer.rb +196 -0
- data/lib/phusion_passenger/abstract_request_handler.rb +19 -24
- data/lib/phusion_passenger/abstract_server.rb +17 -12
- data/lib/phusion_passenger/abstract_server_collection.rb +17 -12
- data/lib/phusion_passenger/admin_tools.rb +23 -0
- data/lib/phusion_passenger/admin_tools/control_process.rb +39 -13
- data/lib/phusion_passenger/application.rb +17 -12
- data/lib/phusion_passenger/console_text_template.rb +17 -12
- data/lib/phusion_passenger/constants.rb +22 -11
- data/lib/phusion_passenger/dependencies.rb +47 -12
- data/lib/phusion_passenger/events.rb +17 -12
- data/lib/phusion_passenger/exceptions.rb +17 -12
- data/lib/phusion_passenger/html_template.rb +17 -12
- data/lib/phusion_passenger/message_channel.rb +17 -12
- data/lib/phusion_passenger/packaging.rb +39 -0
- data/lib/phusion_passenger/platform_info.rb +48 -22
- data/lib/phusion_passenger/rack/application_spawner.rb +22 -11
- data/lib/phusion_passenger/rack/request_handler.rb +21 -12
- data/lib/phusion_passenger/railz/application_spawner.rb +23 -23
- data/lib/phusion_passenger/railz/framework_spawner.rb +18 -14
- data/lib/phusion_passenger/railz/request_handler.rb +18 -11
- data/lib/phusion_passenger/simple_benchmarking.rb +17 -12
- data/lib/phusion_passenger/spawn_manager.rb +17 -20
- data/lib/phusion_passenger/templates/{apache_must_be_compiled_with_compatible_mpm.txt.erb → apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{apache2_config_snippets.txt.erb → apache2/config_snippets.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{deployment_example.txt.erb → apache2/deployment_example.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{no_write_permission_to_passenger_root.txt.erb → apache2/no_write_permission_to_passenger_root.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{possible_solutions_for_compilation_and_installation_problems.txt.erb → apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{run_installer_as_root.txt.erb → apache2/run_installer_as_root.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/{welcome.txt.erb → apache2/welcome.txt.erb} +0 -0
- data/lib/phusion_passenger/templates/nginx/ask_for_extra_configure_flags.txt.erb +8 -0
- data/lib/phusion_passenger/templates/nginx/cannot_write_to_dir.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/config_snippets.txt.erb +17 -0
- data/lib/phusion_passenger/templates/nginx/config_snippets_inserted.txt.erb +20 -0
- data/lib/phusion_passenger/templates/nginx/confirm_extra_configure_flags.txt.erb +5 -0
- data/lib/phusion_passenger/templates/nginx/deployment_example.txt.erb +22 -0
- data/lib/phusion_passenger/templates/nginx/pcre_could_not_be_downloaded.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/pcre_could_not_be_extracted.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +11 -0
- data/lib/phusion_passenger/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +20 -0
- data/lib/phusion_passenger/templates/nginx/query_download_and_install.txt.erb +21 -0
- data/lib/phusion_passenger/templates/nginx/run_installer_as_root.txt.erb +8 -0
- data/lib/phusion_passenger/templates/nginx/welcome.txt.erb +15 -0
- data/lib/phusion_passenger/utils.rb +20 -15
- data/lib/phusion_passenger/wsgi/application_spawner.rb +18 -11
- data/lib/phusion_passenger/wsgi/request_handler.py +23 -0
- data/misc/copy_boost_headers.rb +23 -0
- data/misc/find_owner_pipe_leaks.rb +18 -11
- data/misc/rake/cplusplus.rb +18 -11
- data/misc/rake/extensions.rb +21 -14
- data/misc/render_error_pages.rb +18 -11
- data/test/ApplicationPoolServerTest.cpp +1 -3
- data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +1 -1
- data/test/CxxTestMain.cpp +19 -3
- data/test/HttpStatusExtractorTest.cpp +181 -0
- data/test/ScgiRequestParserTest.cpp +337 -0
- data/test/StaticStringTest.cpp +51 -0
- data/test/UtilsTest.cpp +32 -0
- data/test/config.yml.example +5 -0
- data/test/{integration_tests.rb → integration_tests/apache2_tests.rb} +7 -299
- data/test/integration_tests/hello_world_rack_spec.rb +36 -0
- data/test/integration_tests/hello_world_wsgi_spec.rb +41 -0
- data/test/integration_tests/mycook_spec.rb +192 -0
- data/test/integration_tests/nginx_tests.rb +98 -0
- data/test/ruby/rack/application_spawner_spec.rb +40 -0
- data/test/stub/nginx/koi-utf +109 -0
- data/test/stub/nginx/koi-win +103 -0
- data/test/stub/nginx/mime.types +70 -0
- data/test/stub/nginx/nginx.conf.erb +57 -0
- data/test/stub/nginx/win-utf +126 -0
- data/test/stub/rails_apps/mycook/app/controllers/uploads_controller.rb +4 -0
- data/test/stub/rails_apps/mycook/config/routes.rb +1 -1
- data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
- data/test/support/Support.h +40 -0
- data/test/support/nginx_controller.rb +98 -0
- data/test/support/test_helper.rb +79 -0
- metadata +1091 -1028
- data/benchmark/DummyRequestHandler.cpp +0 -101
- data/ext/apache2/Logging.cpp +0 -60
- data/ext/apache2/SystemTime.cpp +0 -28
@@ -0,0 +1,337 @@
|
|
1
|
+
#include "tut.h"
|
2
|
+
#include "ScgiRequestParser.h"
|
3
|
+
|
4
|
+
using namespace Passenger;
|
5
|
+
using namespace std;
|
6
|
+
|
7
|
+
namespace tut {
|
8
|
+
struct ScgiRequestParserTest {
|
9
|
+
ScgiRequestParser parser;
|
10
|
+
};
|
11
|
+
|
12
|
+
DEFINE_TEST_GROUP(ScgiRequestParserTest);
|
13
|
+
|
14
|
+
TEST_METHOD(1) {
|
15
|
+
// It has an initial state of READING_LENGTH_STRING and does
|
16
|
+
// not have anything in its header data buffer.
|
17
|
+
ensure_equals(parser.getState(), ScgiRequestParser::READING_LENGTH_STRING);
|
18
|
+
ensure(parser.getHeaderData().empty());
|
19
|
+
}
|
20
|
+
|
21
|
+
/***** Test parsing a complete SCGI request in a single pass. *****/
|
22
|
+
|
23
|
+
TEST_METHOD(2) {
|
24
|
+
// Parsing a request with a single header and no body.
|
25
|
+
static const char data[] = "12:hello\0world\0,";
|
26
|
+
ensure_equals("It accepted all input.",
|
27
|
+
parser.feed(data, sizeof(data) - 1),
|
28
|
+
sizeof(data) - 1);
|
29
|
+
ensure_equals("It is in the accepting state.",
|
30
|
+
parser.getState(), ScgiRequestParser::DONE);
|
31
|
+
ensure_equals("It parsed the header data.",
|
32
|
+
parser.getHeaderData(),
|
33
|
+
string("hello\0world\0", 12));
|
34
|
+
ensure(parser.getHeader("hello") == "world");
|
35
|
+
}
|
36
|
+
|
37
|
+
TEST_METHOD(3) {
|
38
|
+
// Parsing a request with a single header and a body.
|
39
|
+
static const char data[] = "12:hello\0world\0,data";
|
40
|
+
ensure_equals("It accepted all input.",
|
41
|
+
parser.feed(data, sizeof(data) - 1 - 4),
|
42
|
+
sizeof(data) - 1 - 4);
|
43
|
+
ensure_equals("It is in the accepting state.",
|
44
|
+
parser.getState(), ScgiRequestParser::DONE);
|
45
|
+
ensure_equals("It parsed the header data.",
|
46
|
+
parser.getHeaderData(),
|
47
|
+
string("hello\0world\0", 12));
|
48
|
+
ensure(parser.getHeader("hello") == "world");
|
49
|
+
}
|
50
|
+
|
51
|
+
TEST_METHOD(4) {
|
52
|
+
// Parsing a request with multiple headers and no body.
|
53
|
+
static const char data[] = "19:hello\0world\0SCGI\0001\0,";
|
54
|
+
ensure_equals("It accepted all input.",
|
55
|
+
parser.feed(data, sizeof(data) - 1),
|
56
|
+
sizeof(data) - 1);
|
57
|
+
ensure_equals("It is in the accepting state.",
|
58
|
+
parser.getState(), ScgiRequestParser::DONE);
|
59
|
+
ensure_equals("It parsed the header data.",
|
60
|
+
parser.getHeaderData(),
|
61
|
+
string("hello\0world\0SCGI\0001\0", 19));
|
62
|
+
ensure(parser.getHeader("hello") == "world");
|
63
|
+
ensure(parser.getHeader("SCGI") == "1");
|
64
|
+
}
|
65
|
+
|
66
|
+
TEST_METHOD(5) {
|
67
|
+
// Parsing a request with multiple headers and a body.
|
68
|
+
static const char data[] = "19:hello\0world\0SCGI\0001\0,body";
|
69
|
+
ensure_equals("It accepted all input.",
|
70
|
+
parser.feed(data, sizeof(data) - 1 - 4),
|
71
|
+
sizeof(data) - 1 - 4);
|
72
|
+
ensure_equals("It is in the accepting state.",
|
73
|
+
parser.getState(), ScgiRequestParser::DONE);
|
74
|
+
ensure_equals("It parsed the header data.",
|
75
|
+
parser.getHeaderData(),
|
76
|
+
string("hello\0world\0SCGI\0001\0", 19));
|
77
|
+
ensure(parser.getHeader("hello") == "world");
|
78
|
+
ensure(parser.getHeader("SCGI") == "1");
|
79
|
+
}
|
80
|
+
|
81
|
+
/***** Test parsing a complete SCGI request in multiple passes. *****/
|
82
|
+
|
83
|
+
TEST_METHOD(8) {
|
84
|
+
// Parsing a request with multiple headers and a body.
|
85
|
+
// 1 byte per pass.
|
86
|
+
static const char data[] = "20:hello\0world\0foo\0bar\0,data";
|
87
|
+
for (unsigned int i = 0; i < sizeof(data) - 1 - 4; i++) {
|
88
|
+
ensure_equals(parser.feed(&data[i], 1), 1u);
|
89
|
+
}
|
90
|
+
ensure_equals("It is in the accepting state.",
|
91
|
+
parser.getState(), ScgiRequestParser::DONE);
|
92
|
+
ensure_equals("It parsed the header data.",
|
93
|
+
parser.getHeaderData(),
|
94
|
+
string("hello\0world\0foo\0bar\0", 20));
|
95
|
+
ensure(parser.getHeader("hello") == "world");
|
96
|
+
ensure(parser.getHeader("foo") == "bar");
|
97
|
+
}
|
98
|
+
|
99
|
+
TEST_METHOD(9) {
|
100
|
+
// Parsing a request with multiple headers and a body.
|
101
|
+
// Half element per pass.
|
102
|
+
ensure_equals(parser.feed("2", 1), 1u);
|
103
|
+
ensure_equals(parser.feed("0", 1), 1u);
|
104
|
+
ensure_equals(parser.feed(":", 1), 1u);
|
105
|
+
ensure_equals(parser.feed("hello\0world\0", 12), 12u);
|
106
|
+
ensure_equals(parser.feed("foo\0bar\0", 8), 8u);
|
107
|
+
ensure_equals(parser.feed(",", 1), 1u);
|
108
|
+
ensure_equals(parser.feed("da", 2), 0u);
|
109
|
+
ensure_equals(parser.feed("ta", 2), 0u);
|
110
|
+
ensure_equals("It is in the accepting state.",
|
111
|
+
parser.getState(), ScgiRequestParser::DONE);
|
112
|
+
ensure_equals("It parsed the header data.",
|
113
|
+
parser.getHeaderData(),
|
114
|
+
string("hello\0world\0foo\0bar\0", 20));
|
115
|
+
ensure(parser.getHeader("hello") == "world");
|
116
|
+
ensure(parser.getHeader("foo") == "bar");
|
117
|
+
}
|
118
|
+
|
119
|
+
TEST_METHOD(10) {
|
120
|
+
// Parsing a request with multiple headers and a body.
|
121
|
+
// 1 element per pass.
|
122
|
+
ensure_equals(parser.feed("20", 2), 2u);
|
123
|
+
ensure_equals(parser.feed(":", 1), 1u);
|
124
|
+
ensure_equals(parser.feed("hello\0world\0foo\0bar\0", 20), 20u);
|
125
|
+
ensure_equals(parser.feed(",", 1), 1u);
|
126
|
+
ensure_equals(parser.feed("data", 4), 0u);
|
127
|
+
ensure_equals("It is in the accepting state.",
|
128
|
+
parser.getState(), ScgiRequestParser::DONE);
|
129
|
+
ensure_equals("It parsed the header data.",
|
130
|
+
parser.getHeaderData(),
|
131
|
+
string("hello\0world\0foo\0bar\0", 20));
|
132
|
+
ensure(parser.getHeader("hello") == "world");
|
133
|
+
ensure(parser.getHeader("foo") == "bar");
|
134
|
+
}
|
135
|
+
|
136
|
+
TEST_METHOD(11) {
|
137
|
+
// Parsing a request with multiple headers and a body.
|
138
|
+
// 2 elements per pass.
|
139
|
+
ensure_equals(parser.feed("20:", 3), 3u);
|
140
|
+
ensure_equals(parser.feed("hello\0world\0foo\0bar\0,", 21), 21u);
|
141
|
+
ensure_equals(parser.feed("data", 4), 0u);
|
142
|
+
ensure_equals("It is in the accepting state.",
|
143
|
+
parser.getState(), ScgiRequestParser::DONE);
|
144
|
+
ensure_equals("It parsed the header data.",
|
145
|
+
parser.getHeaderData(),
|
146
|
+
string("hello\0world\0foo\0bar\0", 20));
|
147
|
+
ensure(parser.getHeader("hello") == "world");
|
148
|
+
ensure(parser.getHeader("foo") == "bar");
|
149
|
+
}
|
150
|
+
|
151
|
+
TEST_METHOD(12) {
|
152
|
+
// Parsing a request with multiple headers and a body.
|
153
|
+
// Variable number of elements per pass.
|
154
|
+
ensure_equals(parser.feed("20:h", 4), 4u);
|
155
|
+
ensure_equals(parser.feed("ello\0world\0foo\0bar", 18), 18u);
|
156
|
+
ensure_equals(parser.feed("\0,data", 6), 2u);
|
157
|
+
ensure_equals("It is in the accepting state.",
|
158
|
+
parser.getState(), ScgiRequestParser::DONE);
|
159
|
+
ensure_equals("It parsed the header data.",
|
160
|
+
parser.getHeaderData(),
|
161
|
+
string("hello\0world\0foo\0bar\0", 20));
|
162
|
+
ensure(parser.getHeader("hello") == "world");
|
163
|
+
ensure(parser.getHeader("foo") == "bar");
|
164
|
+
}
|
165
|
+
|
166
|
+
/***** Test parsing invalid SCGI requests in one pass. *****/
|
167
|
+
|
168
|
+
TEST_METHOD(16) {
|
169
|
+
// Invalid first character for length string.
|
170
|
+
ensure_equals("Parser did not accept anything.",
|
171
|
+
parser.feed("hello world!", 12), 0u);
|
172
|
+
ensure_equals("Parser is in the error state.",
|
173
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
174
|
+
}
|
175
|
+
|
176
|
+
TEST_METHOD(17) {
|
177
|
+
// Invalid character inside length string.
|
178
|
+
ensure_equals(parser.feed("12x:hello world!", 16), 2u);
|
179
|
+
ensure_equals("Parser is in the error state.",
|
180
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
181
|
+
}
|
182
|
+
|
183
|
+
TEST_METHOD(18) {
|
184
|
+
// Invalid character in place of colon.
|
185
|
+
ensure_equals(parser.feed("12#hello world!", 15), 2u);
|
186
|
+
ensure_equals("Parser is in the error state.",
|
187
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
188
|
+
}
|
189
|
+
|
190
|
+
TEST_METHOD(19) {
|
191
|
+
// Invalid character in place of comma.
|
192
|
+
ensure_equals(parser.feed("12:hello\0world\0!", 16), 15u);
|
193
|
+
ensure_equals("Parser is in the error state.",
|
194
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
195
|
+
}
|
196
|
+
|
197
|
+
TEST_METHOD(20) {
|
198
|
+
// Only a header name, without even a null terminator.
|
199
|
+
ensure_equals(parser.feed("5:hello,", 8), 7u);
|
200
|
+
ensure_equals("Parser is in the error state.",
|
201
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
202
|
+
}
|
203
|
+
|
204
|
+
TEST_METHOD(21) {
|
205
|
+
// Only a header name, with a null terminator.
|
206
|
+
ensure_equals(parser.feed("6:hello\0,", 9), 8u);
|
207
|
+
ensure_equals("Parser is in the error state.",
|
208
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
209
|
+
}
|
210
|
+
|
211
|
+
TEST_METHOD(22) {
|
212
|
+
// A header name with its value not having a null terminator.
|
213
|
+
ensure_equals(parser.feed("7:foo\0bar,", 10), 9u);
|
214
|
+
ensure_equals("Parser is in the error state.",
|
215
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
216
|
+
}
|
217
|
+
|
218
|
+
TEST_METHOD(23) {
|
219
|
+
// A header name without corresponding value.
|
220
|
+
ensure_equals(parser.feed("10:foo\0bar\0a\0,", 14), 13u);
|
221
|
+
ensure_equals("Parser is in the error state.",
|
222
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
223
|
+
}
|
224
|
+
|
225
|
+
TEST_METHOD(24) {
|
226
|
+
// Length string is too large.
|
227
|
+
static const char data[] = "999999999999999999999";
|
228
|
+
ensure(parser.feed(data, sizeof(data) - 1) < sizeof(data) - 1);
|
229
|
+
ensure_equals("Parser is in the error state.",
|
230
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
231
|
+
}
|
232
|
+
|
233
|
+
/***** Test parsing invalid SCGI requests in multiple passes. *****/
|
234
|
+
|
235
|
+
TEST_METHOD(27) {
|
236
|
+
// Once the parser has entered the error state, it stays there.
|
237
|
+
ensure_equals(parser.feed("hello world!", 12), 0u);
|
238
|
+
ensure_equals(parser.feed("1", 1), 0u);
|
239
|
+
ensure_equals("Parser is in the error state.",
|
240
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
241
|
+
}
|
242
|
+
|
243
|
+
TEST_METHOD(28) {
|
244
|
+
// Invalid character inside length string.
|
245
|
+
ensure_equals(parser.feed("12", 2), 2u);
|
246
|
+
ensure_equals(parser.feed("x:", 2), 0u);
|
247
|
+
ensure_equals("Parser is in the error state.",
|
248
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
249
|
+
}
|
250
|
+
|
251
|
+
TEST_METHOD(29) {
|
252
|
+
// Invalid character in place of colon.
|
253
|
+
ensure_equals(parser.feed("12", 2), 2u);
|
254
|
+
ensure_equals(parser.feed("#", 1), 0u);
|
255
|
+
ensure_equals("Parser is in the error state.",
|
256
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
257
|
+
}
|
258
|
+
|
259
|
+
TEST_METHOD(30) {
|
260
|
+
// Invalid character in place of comma.
|
261
|
+
ensure_equals(parser.feed("12:hello\0world\0", 15), 15u);
|
262
|
+
ensure_equals(parser.feed("!", 1), 0u);
|
263
|
+
ensure_equals("Parser is in the error state.",
|
264
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
265
|
+
}
|
266
|
+
|
267
|
+
TEST_METHOD(31) {
|
268
|
+
// Only a header name, without even a null terminator.
|
269
|
+
ensure_equals(parser.feed("5:hell", 6), 6u);
|
270
|
+
ensure_equals(parser.feed("o,", 1), 1u);
|
271
|
+
ensure_equals("Parser is in the error state.",
|
272
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
273
|
+
}
|
274
|
+
|
275
|
+
TEST_METHOD(32) {
|
276
|
+
// Only a header name, with a null terminator.
|
277
|
+
ensure_equals(parser.feed("6:hello", 7), 7u);
|
278
|
+
ensure_equals(parser.feed("\0,", 1), 1u);
|
279
|
+
ensure_equals("Parser is in the error state.",
|
280
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
281
|
+
}
|
282
|
+
|
283
|
+
TEST_METHOD(33) {
|
284
|
+
// A header name with its value not having a null terminator.
|
285
|
+
ensure_equals(parser.feed("7:foo\0ba", 8), 8u);
|
286
|
+
ensure_equals(parser.feed("r,", 2), 1u);
|
287
|
+
ensure_equals("Parser is in the error state.",
|
288
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
289
|
+
}
|
290
|
+
|
291
|
+
TEST_METHOD(34) {
|
292
|
+
// A header name without corresponding value.
|
293
|
+
ensure_equals(parser.feed("10:foo\0bar\0a", 12), 12u);
|
294
|
+
ensure_equals(parser.feed("\0,", 2), 1u);
|
295
|
+
ensure_equals("Parser is in the error state.",
|
296
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
297
|
+
}
|
298
|
+
|
299
|
+
TEST_METHOD(35) {
|
300
|
+
// Length string is too large.
|
301
|
+
static const char data[] = "999999999999999999999";
|
302
|
+
ensure_equals(parser.feed("99", 2), 2u);
|
303
|
+
ensure(parser.feed(data, sizeof(data) - 1) < sizeof(data) - 1);
|
304
|
+
ensure_equals("Parser is in the error state.",
|
305
|
+
parser.getState(), ScgiRequestParser::ERROR);
|
306
|
+
}
|
307
|
+
|
308
|
+
/***** Test parsing incomplete SCGI requests. *****/
|
309
|
+
|
310
|
+
TEST_METHOD(40) {
|
311
|
+
// Incomplete length string.
|
312
|
+
ensure_equals(parser.feed("2", 1), 1u);
|
313
|
+
ensure_equals("Parser is still waiting for length string input.",
|
314
|
+
parser.getState(), ScgiRequestParser::READING_LENGTH_STRING);
|
315
|
+
}
|
316
|
+
|
317
|
+
TEST_METHOD(41) {
|
318
|
+
// Incomplete header.
|
319
|
+
ensure_equals(parser.feed("21:", 3), 3u);
|
320
|
+
ensure_equals("Parser is waiting for header data input.",
|
321
|
+
parser.getState(), ScgiRequestParser::READING_HEADER_DATA);
|
322
|
+
}
|
323
|
+
|
324
|
+
TEST_METHOD(42) {
|
325
|
+
// Incomplete header.
|
326
|
+
ensure_equals(parser.feed("20:hel", 6), 6u);
|
327
|
+
ensure_equals("Parser is waiting for header data input.",
|
328
|
+
parser.getState(), ScgiRequestParser::READING_HEADER_DATA);
|
329
|
+
}
|
330
|
+
|
331
|
+
TEST_METHOD(43) {
|
332
|
+
// Complete header but no comma.
|
333
|
+
ensure_equals(parser.feed("8:foo\0bar\0", 10), 10u);
|
334
|
+
ensure_equals("Parser is waiting for comma.",
|
335
|
+
parser.getState(), ScgiRequestParser::EXPECTING_COMMA);
|
336
|
+
}
|
337
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#include "tut.h"
|
2
|
+
#include "StaticString.h"
|
3
|
+
|
4
|
+
using namespace Passenger;
|
5
|
+
using namespace std;
|
6
|
+
|
7
|
+
namespace tut {
|
8
|
+
struct StaticStringTest {
|
9
|
+
};
|
10
|
+
|
11
|
+
DEFINE_TEST_GROUP(StaticStringTest);
|
12
|
+
|
13
|
+
TEST_METHOD(1) {
|
14
|
+
// Test == operator.
|
15
|
+
ensure(StaticString("") == "");
|
16
|
+
ensure(StaticString("foo") == "foo");
|
17
|
+
ensure(!(StaticString("foo") == "bar"));
|
18
|
+
}
|
19
|
+
|
20
|
+
TEST_METHOD(2) {
|
21
|
+
// Test < operator.
|
22
|
+
ensure_equals("Assertion 1",
|
23
|
+
StaticString("") < "",
|
24
|
+
string("") < string("")
|
25
|
+
);
|
26
|
+
ensure_equals("Assertion 2",
|
27
|
+
StaticString("abc") < "abc",
|
28
|
+
string("abc") < string("abc")
|
29
|
+
);
|
30
|
+
ensure_equals("Assertion 3",
|
31
|
+
StaticString("foo") < "bar",
|
32
|
+
string("foo") < string("bar")
|
33
|
+
);
|
34
|
+
ensure_equals("Assertion 4",
|
35
|
+
StaticString("foo") < "bar!",
|
36
|
+
string("foo") < string("bar!")
|
37
|
+
);
|
38
|
+
ensure_equals("Assertion 5",
|
39
|
+
StaticString("bar!") < "foo",
|
40
|
+
string("bar!") < string("foo")
|
41
|
+
);
|
42
|
+
ensure_equals("Assertion 6",
|
43
|
+
StaticString("hello") < "hello world",
|
44
|
+
string("hello") < string("hello world")
|
45
|
+
);
|
46
|
+
ensure_equals("Assertion 7",
|
47
|
+
StaticString("hello world") < "hello",
|
48
|
+
string("hello world") < string("hello")
|
49
|
+
);
|
50
|
+
}
|
51
|
+
}
|
data/test/UtilsTest.cpp
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#include "tut.h"
|
2
2
|
#include "Utils.h"
|
3
|
+
#include "support/Support.h"
|
3
4
|
#include <sys/types.h>
|
4
5
|
#include <sys/stat.h>
|
5
6
|
#include <stdio.h>
|
@@ -10,6 +11,7 @@
|
|
10
11
|
|
11
12
|
using namespace Passenger;
|
12
13
|
using namespace std;
|
14
|
+
using namespace Test;
|
13
15
|
|
14
16
|
namespace tut {
|
15
17
|
struct UtilsTest {
|
@@ -245,4 +247,34 @@ namespace tut {
|
|
245
247
|
ensure_equals(escapeForXml("hello\xFF\xCCworld"), "helloÿÌworld");
|
246
248
|
ensure_equals(escapeForXml("hello\xFFworld\xCC"), "helloÿworldÌ");
|
247
249
|
}
|
250
|
+
|
251
|
+
/***** Test extractDirName() *****/
|
252
|
+
|
253
|
+
TEST_METHOD(26) {
|
254
|
+
ensure_equals("Test 1", extractDirName("/usr/lib"), "/usr");
|
255
|
+
ensure_equals("Test 2", extractDirName("/usr/lib/"), "/usr");
|
256
|
+
ensure_equals("Test 3", extractDirName("/usr/"), "/");
|
257
|
+
ensure_equals("Test 4", extractDirName("usr"), ".");
|
258
|
+
ensure_equals("Test 5", extractDirName("/"), "/");
|
259
|
+
ensure_equals("Test 6", extractDirName("///"), "/");
|
260
|
+
ensure_equals("Test 7", extractDirName("."), ".");
|
261
|
+
ensure_equals("Test 8", extractDirName(".."), ".");
|
262
|
+
ensure_equals("Test 9", extractDirName("./foo"), ".");
|
263
|
+
ensure_equals("Test 10", extractDirName("../foo"), "..");
|
264
|
+
}
|
265
|
+
|
266
|
+
/***** Test resolveSymlink() *****/
|
267
|
+
|
268
|
+
TEST_METHOD(27) {
|
269
|
+
TempDir d("tmp.symlinks");
|
270
|
+
system("touch tmp.symlinks/foo.txt");
|
271
|
+
system("ln -s /usr/bin tmp.symlinks/absolute_symlink");
|
272
|
+
system("ln -s foo.txt tmp.symlinks/file");
|
273
|
+
system("ln -s file tmp.symlinks/file2");
|
274
|
+
system("ln -s file2 tmp.symlinks/file3");
|
275
|
+
ensure_equals(resolveSymlink("tmp.symlinks/file"), "tmp.symlinks/foo.txt");
|
276
|
+
ensure_equals(resolveSymlink("tmp.symlinks/file2"), "tmp.symlinks/file");
|
277
|
+
ensure_equals(resolveSymlink("tmp.symlinks/file3"), "tmp.symlinks/file2");
|
278
|
+
ensure_equals(resolveSymlink("tmp.symlinks/absolute_symlink"), "/usr/bin");
|
279
|
+
}
|
248
280
|
}
|
data/test/config.yml.example
CHANGED
@@ -23,3 +23,8 @@ nonexistant_user: xxxxxxxxxxxxxxxxxxx
|
|
23
23
|
# A nonexistant user ID.
|
24
24
|
nonexistant_uid: 9999
|
25
25
|
|
26
|
+
|
27
|
+
# If you want to run the Nginx integration tests, then set the following
|
28
|
+
# config option to the full path of the Nginx binary. This Nginx binary *must*
|
29
|
+
# be compiled with Phusion Passenger support!
|
30
|
+
# nginx: /usr/local/sbin/nginx
|
@@ -1,254 +1,17 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'uri'
|
3
|
-
require 'resolv'
|
4
1
|
require 'socket'
|
5
2
|
require 'fileutils'
|
6
|
-
require 'timeout'
|
7
3
|
require 'support/config'
|
8
4
|
require 'support/test_helper'
|
9
|
-
require 'support/multipart'
|
10
5
|
require 'support/apache2_controller'
|
11
6
|
require 'phusion_passenger/platform_info'
|
12
7
|
|
8
|
+
require 'integration_tests/mycook_spec'
|
9
|
+
require 'integration_tests/hello_world_rack_spec'
|
10
|
+
require 'integration_tests/hello_world_wsgi_spec'
|
11
|
+
|
13
12
|
# TODO: test the 'RailsUserSwitching' and 'RailsDefaultUser' option.
|
14
13
|
# TODO: test custom page caching directory
|
15
14
|
|
16
|
-
shared_examples_for "MyCook(tm) beta" do
|
17
|
-
it "is possible to fetch static assets" do
|
18
|
-
get('/images/rails.png').should == public_file('images/rails.png')
|
19
|
-
end
|
20
|
-
|
21
|
-
it "supports page caching on non-index URIs" do
|
22
|
-
get('/welcome/cached').should =~ %r{This is the cached version of /welcome/cached}
|
23
|
-
end
|
24
|
-
|
25
|
-
it "supports page caching on index URIs" do
|
26
|
-
get('/uploads').should =~ %r{This is the cached version of /uploads}
|
27
|
-
end
|
28
|
-
|
29
|
-
it "doesn't use page caching if the HTTP request is not GET" do
|
30
|
-
post('/welcome/cached').should =~ %r{This content should never be displayed}
|
31
|
-
end
|
32
|
-
|
33
|
-
it "isn't interfered by Rails's default .htaccess dispatcher rules" do
|
34
|
-
get('/welcome/in_passenger').should == 'true'
|
35
|
-
end
|
36
|
-
|
37
|
-
it "is possible to GET a regular Rails page" do
|
38
|
-
get('/').should =~ /Welcome to MyCook/
|
39
|
-
end
|
40
|
-
|
41
|
-
it "is possible to pass GET parameters to a Rails page" do
|
42
|
-
result = get('/welcome/parameters_test?hello=world&recipe[name]=Green+Bananas')
|
43
|
-
result.should =~ %r{<hello>world</hello>}
|
44
|
-
result.should =~ %r{<recipe>}
|
45
|
-
result.should =~ %r{<name>Green Bananas</name>}
|
46
|
-
end
|
47
|
-
|
48
|
-
it "is possible to POST to a Rails page" do
|
49
|
-
result = post('/recipes', {
|
50
|
-
'recipe[name]' => 'Banana Pancakes',
|
51
|
-
'recipe[instructions]' => 'Call 0900-BANANAPANCAKES'
|
52
|
-
})
|
53
|
-
result.should =~ %r{HTTP method: post}
|
54
|
-
result.should =~ %r{Name: Banana Pancakes}
|
55
|
-
result.should =~ %r{Instructions: Call 0900-BANANAPANCAKES}
|
56
|
-
end
|
57
|
-
|
58
|
-
it "is possible to upload a file" do
|
59
|
-
rails_png = File.open("#{@stub.app_root}/public/images/rails.png", 'rb')
|
60
|
-
params = {
|
61
|
-
'upload[name1]' => 'Kotonoha',
|
62
|
-
'upload[name2]' => 'Sekai',
|
63
|
-
'upload[data]' => rails_png
|
64
|
-
}
|
65
|
-
begin
|
66
|
-
response = post('/uploads', params)
|
67
|
-
rails_png.rewind
|
68
|
-
response.should ==
|
69
|
-
"name 1 = Kotonoha\n" <<
|
70
|
-
"name 2 = Sekai\n" <<
|
71
|
-
"data = " << rails_png.read
|
72
|
-
ensure
|
73
|
-
rails_png.close
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
it "can properly handle custom headers" do
|
78
|
-
response = get_response('/welcome/headers_test')
|
79
|
-
response["X-Foo"].should == "Bar"
|
80
|
-
end
|
81
|
-
|
82
|
-
it "supports %2f in URIs" do
|
83
|
-
get('/welcome/show_id/foo%2fbar').should == 'foo/bar'
|
84
|
-
end
|
85
|
-
|
86
|
-
it "has AbstractRequest which returns a request_uri without hostname, with query_string" do
|
87
|
-
get('/welcome/request_uri?foo=bar%20escaped').should =~ %r{/welcome/request_uri\?foo=bar%20escaped}
|
88
|
-
end
|
89
|
-
|
90
|
-
it "supports restarting via restart.txt" do
|
91
|
-
begin
|
92
|
-
controller = "#{@stub.app_root}/app/controllers/test_controller.rb"
|
93
|
-
restart_file = "#{@stub.app_root}/tmp/restart.txt"
|
94
|
-
now = Time.now
|
95
|
-
|
96
|
-
File.open(controller, 'w') do |f|
|
97
|
-
f.write %q{
|
98
|
-
class TestController < ApplicationController
|
99
|
-
layout nil
|
100
|
-
def index
|
101
|
-
render :text => "foo"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
}
|
105
|
-
end
|
106
|
-
File.open(restart_file, 'w').close
|
107
|
-
File.utime(now - 10, now - 10, restart_file)
|
108
|
-
get('/test').should == "foo"
|
109
|
-
|
110
|
-
File.open(controller, 'w') do |f|
|
111
|
-
f.write %q{
|
112
|
-
class TestController < ApplicationController
|
113
|
-
layout nil
|
114
|
-
def index
|
115
|
-
render :text => "bar"
|
116
|
-
end
|
117
|
-
end
|
118
|
-
}
|
119
|
-
end
|
120
|
-
|
121
|
-
File.utime(now - 5, now - 5, restart_file)
|
122
|
-
get('/test').should == 'bar'
|
123
|
-
ensure
|
124
|
-
File.unlink(controller) rescue nil
|
125
|
-
File.unlink(restart_file) rescue nil
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
it "does not make the web server crash if the app crashes" do
|
130
|
-
post('/welcome/terminate')
|
131
|
-
sleep(0.25) # Give the app the time to terminate itself.
|
132
|
-
get('/').should =~ /Welcome to MyCook/
|
133
|
-
end
|
134
|
-
|
135
|
-
it "does not conflict with Phusion Passenger if there's a model named 'Passenger'" do
|
136
|
-
Dir.mkdir("#{@stub.app_root}/app/models") rescue nil
|
137
|
-
File.open("#{@stub.app_root}/app/models/passenger.rb", 'w') do |f|
|
138
|
-
f.write(%q{
|
139
|
-
class Passenger
|
140
|
-
def name
|
141
|
-
return "Gourry Gabriev"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
})
|
145
|
-
end
|
146
|
-
begin
|
147
|
-
system "touch '#{@stub.app_root}/tmp/restart.txt'"
|
148
|
-
get('/welcome/passenger_name').should == 'Gourry Gabriev'
|
149
|
-
ensure
|
150
|
-
File.unlink("#{@stub.app_root}/app/models/passenger.rb") rescue nil
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
it "sets the 'Status' header" do
|
155
|
-
response = get_response('/nonexistant')
|
156
|
-
response["Status"].should == "404 Not Found"
|
157
|
-
end
|
158
|
-
|
159
|
-
if Process.uid == 0
|
160
|
-
it "runs as an unprivileged user" do
|
161
|
-
post('/welcome/touch')
|
162
|
-
begin
|
163
|
-
stat = File.stat("#{@stub.app_root}/public/touch.txt")
|
164
|
-
stat.uid.should_not == 0
|
165
|
-
stat.gid.should_not == 0
|
166
|
-
ensure
|
167
|
-
File.unlink("#{@stub.app_root}/public/touch.txt") rescue nil
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
shared_examples_for "HelloWorld Rack application" do
|
174
|
-
it "is possible to fetch static assets" do
|
175
|
-
get('/rack.jpg').should == public_file('rack.jpg')
|
176
|
-
end
|
177
|
-
|
178
|
-
it "is possible to GET a regular Rack page" do
|
179
|
-
get('/').should =~ /hello/
|
180
|
-
end
|
181
|
-
|
182
|
-
it "supports restarting via restart.txt" do
|
183
|
-
get('/').should =~ /hello/
|
184
|
-
File.write("#{@stub.app_root}/config.ru", %q{
|
185
|
-
app = lambda do |env|
|
186
|
-
[200, { "Content-Type" => "text/html" }, "changed"]
|
187
|
-
end
|
188
|
-
run app
|
189
|
-
})
|
190
|
-
File.new("#{@stub.app_root}/tmp/restart.txt", "w").close
|
191
|
-
File.utime(2, 2, "#{@stub.app_root}/tmp/restart.txt")
|
192
|
-
get('/').should == "changed"
|
193
|
-
end
|
194
|
-
|
195
|
-
if Process.uid == 0
|
196
|
-
it "runs as an unprivileged user" do
|
197
|
-
File.prepend("#{@stub.app_root}/config.ru", %q{
|
198
|
-
File.new('foo.txt', 'w').close
|
199
|
-
})
|
200
|
-
File.new("#{@stub.app_root}/tmp/restart.txt", "w").close
|
201
|
-
File.utime(1, 1, "#{@stub.app_root}/tmp/restart.txt")
|
202
|
-
get('/')
|
203
|
-
stat = File.stat("#{@stub.app_root}/foo.txt")
|
204
|
-
stat.uid.should_not == 0
|
205
|
-
stat.gid.should_not == 0
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
shared_examples_for "HelloWorld WSGI application" do
|
211
|
-
after :each do
|
212
|
-
File.unlink("#{@stub.app_root}/passenger_wsgi.pyc") rescue nil
|
213
|
-
end
|
214
|
-
|
215
|
-
it "is possible to fetch static assets" do
|
216
|
-
get('/wsgi-snake.jpg').should == public_file('wsgi-snake.jpg')
|
217
|
-
end
|
218
|
-
|
219
|
-
it "is possible to GET a regular WSGI page" do
|
220
|
-
get('/').should =~ /Hello World/
|
221
|
-
end
|
222
|
-
|
223
|
-
it "supports restarting via restart.txt" do
|
224
|
-
get('/').should =~ /Hello World/
|
225
|
-
|
226
|
-
code = %q{
|
227
|
-
def application(env, start_response):
|
228
|
-
start_response('200 OK', [('Content-Type', 'text/html')])
|
229
|
-
return ["changed"]
|
230
|
-
}.gsub(/^\t\t\t/, '')
|
231
|
-
|
232
|
-
File.write("#{@stub.app_root}/passenger_wsgi.py", code)
|
233
|
-
File.new("#{@stub.app_root}/tmp/restart.txt", "w").close
|
234
|
-
File.utime(2, 2, "#{@stub.app_root}/tmp/restart.txt")
|
235
|
-
get('/').should == "changed"
|
236
|
-
end
|
237
|
-
|
238
|
-
if Process.uid == 0
|
239
|
-
it "runs as an unprivileged user" do
|
240
|
-
File.prepend("#{@stub.app_root}/passenger_wsgi.py",
|
241
|
-
"file('foo.txt', 'w').close()\n")
|
242
|
-
File.new("#{@stub.app_root}/tmp/restart.txt", "w").close
|
243
|
-
File.utime(1, 1, "#{@stub.app_root}/tmp/restart.txt")
|
244
|
-
get('/')
|
245
|
-
stat = File.stat("#{@stub.app_root}/foo.txt")
|
246
|
-
stat.uid.should_not == 0
|
247
|
-
stat.gid.should_not == 0
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
15
|
describe "mod_passenger running in Apache 2" do
|
253
16
|
include TestHelper
|
254
17
|
|
@@ -269,6 +32,7 @@ describe "mod_passenger running in Apache 2" do
|
|
269
32
|
|
270
33
|
describe ": MyCook(tm) beta running on root URI" do
|
271
34
|
before :all do
|
35
|
+
@web_server_supports_chunked_transfer_encoding = true
|
272
36
|
@server = "http://passenger.test:#{@apache2.port}"
|
273
37
|
@stub = setup_rails_stub('mycook')
|
274
38
|
@apache2 << "RailsMaxPoolSize 1"
|
@@ -333,6 +97,7 @@ describe "mod_passenger running in Apache 2" do
|
|
333
97
|
|
334
98
|
describe ": MyCook(tm) beta running in a sub-URI" do
|
335
99
|
before :all do
|
100
|
+
@web_server_supports_chunked_transfer_encoding = true
|
336
101
|
@stub = setup_rails_stub('mycook')
|
337
102
|
FileUtils.rm_rf('tmp.webdir')
|
338
103
|
FileUtils.mkdir_p('tmp.webdir')
|
@@ -733,66 +498,9 @@ describe "mod_passenger running in Apache 2" do
|
|
733
498
|
|
734
499
|
##### Helper methods #####
|
735
500
|
|
736
|
-
def
|
737
|
-
if !@apache2.running?
|
738
|
-
@apache2.start
|
739
|
-
end
|
740
|
-
return Net::HTTP.get(URI.parse("#{@server}#{uri}"))
|
741
|
-
end
|
742
|
-
|
743
|
-
def get_response(uri)
|
744
|
-
if !@apache2.running?
|
745
|
-
@apache2.start
|
746
|
-
end
|
747
|
-
return Net::HTTP.get_response(URI.parse("#{@server}#{uri}"))
|
748
|
-
end
|
749
|
-
|
750
|
-
def post(uri, params = {})
|
501
|
+
def start_web_server_if_necessary
|
751
502
|
if !@apache2.running?
|
752
503
|
@apache2.start
|
753
504
|
end
|
754
|
-
url = URI.parse("#{@server}#{uri}")
|
755
|
-
if params.values.any? { |x| x.respond_to?(:read) }
|
756
|
-
mp = Multipart::MultipartPost.new
|
757
|
-
query, headers = mp.prepare_query(params)
|
758
|
-
Net::HTTP.start(url.host, url.port) do |http|
|
759
|
-
return http.post(url.path, query, headers).body
|
760
|
-
end
|
761
|
-
else
|
762
|
-
return Net::HTTP.post_form(url, params).body
|
763
|
-
end
|
764
|
-
end
|
765
|
-
|
766
|
-
def public_file(name)
|
767
|
-
return File.read("#{@stub.app_root}/public/#{name}")
|
768
|
-
end
|
769
|
-
|
770
|
-
def check_hosts_configuration
|
771
|
-
begin
|
772
|
-
ok = Resolv.getaddress("passenger.test") == "127.0.0.1"
|
773
|
-
rescue Resolv::ResolvError, ArgumentError
|
774
|
-
# There's a bug in Ruby 1.8.6-p287's resolv.rb library, which causes
|
775
|
-
# an ArgumentError to be raised instead of ResolvError when resolving
|
776
|
-
# failed.
|
777
|
-
ok = false
|
778
|
-
end
|
779
|
-
if !ok
|
780
|
-
message = "To run the integration test, you must update " <<
|
781
|
-
"your hosts file.\n" <<
|
782
|
-
"Please add these to your /etc/hosts:\n\n" <<
|
783
|
-
" 127.0.0.1 passenger.test\n" <<
|
784
|
-
" 127.0.0.1 mycook.passenger.test\n" <<
|
785
|
-
" 127.0.0.1 zsfa.passenger.test\n" <<
|
786
|
-
" 127.0.0.1 norails.passenger.test\n"
|
787
|
-
if RUBY_PLATFORM =~ /darwin/
|
788
|
-
message << "\n\nThen run:\n\n" <<
|
789
|
-
" lookupd -flushcache (OS X Tiger)\n\n" <<
|
790
|
-
"-OR-\n\n" <<
|
791
|
-
" dscacheutil -flushcache (OS X Leopard)"
|
792
|
-
end
|
793
|
-
STDERR.puts "---------------------------"
|
794
|
-
STDERR.puts message
|
795
|
-
exit!
|
796
|
-
end
|
797
505
|
end
|
798
506
|
end
|