passenger 3.0.21 → 3.9.1.beta
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 +4 -10
- data/NEWS +19 -27
- data/Rakefile +20 -19
- data/bin/passenger +3 -2
- data/bin/passenger-config +35 -5
- data/bin/passenger-install-apache2-module +12 -12
- data/bin/passenger-install-nginx-module +55 -38
- data/bin/passenger-memory-stats +3 -1
- data/bin/passenger-status +7 -35
- data/build/agents.rb +107 -21
- data/build/apache2.rb +11 -46
- data/build/basics.rb +61 -9
- data/build/common_library.rb +59 -142
- data/build/cxx_tests.rb +111 -110
- data/build/documentation.rb +33 -0
- data/build/misc.rb +30 -12
- data/build/nginx.rb +10 -39
- data/build/oxt_tests.rb +1 -0
- data/build/ruby_extension.rb +1 -5
- data/build/test_basics.rb +3 -2
- data/dev/copy_boost_headers.rb +2 -1
- data/doc/Architectural overview.html +49 -90
- data/doc/DebuggingAndStressTesting.txt.md +49 -0
- data/doc/Packaging.txt.md +254 -0
- data/doc/Security of user switching support.html +35 -66
- data/doc/Users guide Apache.html +588 -758
- data/doc/Users guide Apache.idmap.txt +253 -136
- data/doc/Users guide Apache.txt +154 -109
- data/doc/Users guide Nginx.html +544 -660
- data/doc/Users guide Nginx.idmap.txt +179 -91
- data/doc/Users guide Nginx.txt +192 -118
- data/doc/Users guide Standalone.html +65 -48
- data/doc/Users guide Standalone.idmap.txt +10 -2
- data/doc/Users guide Standalone.txt +4 -0
- data/doc/images/glyphicons-halflings-white.png +0 -0
- data/doc/images/glyphicons-halflings.png +0 -0
- data/doc/images/phusion_banner_small.png +0 -0
- data/doc/images/{smart-lv2.png → smart.png} +0 -0
- data/doc/images/{smart-lv2.svg → smart.svg} +0 -0
- data/doc/templates/bootstrap.min.css +397 -0
- data/doc/templates/markdown.html.erb +117 -0
- data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +2 -1
- data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +26 -48
- data/doc/users_guide_snippets/passenger_spawn_method.txt +18 -30
- data/doc/users_guide_snippets/support_information.txt +30 -0
- data/ext/apache2/Bucket.cpp +9 -26
- data/ext/apache2/Bucket.h +13 -10
- data/ext/apache2/Configuration.cpp +70 -58
- data/ext/apache2/Configuration.hpp +19 -47
- data/ext/apache2/DirectoryMapper.h +7 -7
- data/ext/apache2/Hooks.cpp +150 -313
- data/ext/boost/algorithm/string/detail/case_conv.hpp +4 -2
- data/ext/boost/algorithm/string/detail/find_format.hpp +20 -20
- data/ext/boost/algorithm/string/detail/find_format_all.hpp +23 -23
- data/ext/boost/algorithm/string/detail/find_format_store.hpp +2 -2
- data/ext/boost/algorithm/string/detail/formatter.hpp +25 -0
- data/ext/boost/algorithm/string/formatter.hpp +20 -3
- data/ext/boost/assert.hpp +85 -4
- data/ext/boost/bind/bind.hpp +1 -1
- data/ext/boost/concept/detail/backward_compatibility.hpp +1 -1
- data/ext/boost/concept_check.hpp +140 -64
- data/ext/boost/config.hpp +1 -1
- data/ext/boost/config/auto_link.hpp +8 -6
- data/ext/boost/config/compiler/borland.hpp +12 -2
- data/ext/boost/config/compiler/clang.hpp +89 -30
- data/ext/boost/config/compiler/codegear.hpp +3 -2
- data/ext/boost/config/compiler/common_edg.hpp +7 -5
- data/ext/boost/config/compiler/cray.hpp +61 -0
- data/ext/boost/config/compiler/digitalmars.hpp +9 -1
- data/ext/boost/config/compiler/gcc.hpp +33 -24
- data/ext/boost/config/compiler/gcc_xml.hpp +4 -0
- data/ext/boost/config/compiler/hp_acc.hpp +12 -1
- data/ext/boost/config/compiler/intel.hpp +78 -4
- data/ext/boost/config/compiler/metrowerks.hpp +4 -1
- data/ext/boost/config/compiler/mpw.hpp +4 -1
- data/ext/boost/config/compiler/nvcc.hpp +8 -66
- data/ext/boost/config/compiler/pathscale.hpp +80 -0
- data/ext/boost/config/compiler/pgi.hpp +5 -5
- data/ext/boost/config/compiler/sunpro_cc.hpp +4 -1
- data/ext/boost/config/compiler/vacpp.hpp +37 -13
- data/ext/boost/config/compiler/visualc.hpp +24 -11
- data/ext/boost/config/platform/bsd.hpp +1 -1
- data/ext/boost/config/platform/cray.hpp +18 -0
- data/ext/boost/config/platform/cygwin.hpp +10 -0
- data/ext/boost/config/platform/linux.hpp +5 -0
- data/ext/boost/config/platform/macos.hpp +5 -4
- data/ext/boost/config/platform/symbian.hpp +5 -2
- data/ext/boost/config/platform/vms.hpp +25 -0
- data/ext/boost/config/platform/win32.hpp +7 -1
- data/ext/boost/config/select_compiler_config.hpp +8 -25
- data/ext/boost/config/select_platform_config.hpp +8 -1
- data/ext/boost/config/select_stdlib_config.hpp +9 -1
- data/ext/boost/config/stdlib/dinkumware.hpp +6 -9
- data/ext/boost/config/stdlib/libcomo.hpp +1 -4
- data/ext/boost/config/stdlib/libcpp.hpp +36 -0
- data/ext/boost/config/stdlib/libstdcpp3.hpp +37 -11
- data/ext/boost/config/stdlib/modena.hpp +1 -4
- data/ext/boost/config/stdlib/msl.hpp +1 -4
- data/ext/boost/config/stdlib/roguewave.hpp +9 -6
- data/ext/boost/config/stdlib/sgi.hpp +12 -4
- data/ext/boost/config/stdlib/stlport.hpp +11 -4
- data/ext/boost/config/stdlib/vacpp.hpp +11 -4
- data/ext/boost/config/suffix.hpp +71 -6
- data/ext/boost/config/warning_disable.hpp +1 -1
- data/ext/boost/container/container_fwd.hpp +177 -0
- data/ext/boost/cstdint.hpp +17 -12
- data/ext/boost/current_function.hpp +2 -1
- data/ext/boost/date_time/c_time.hpp +17 -1
- data/ext/boost/date_time/compiler_config.hpp +13 -15
- data/ext/boost/date_time/date_formatting.hpp +7 -1
- data/ext/boost/date_time/filetime_functions.hpp +4 -4
- data/ext/boost/date_time/gregorian_calendar.ipp +2 -2
- data/ext/boost/date_time/strings_from_facet.hpp +3 -3
- data/ext/boost/date_time/time_facet.hpp +101 -101
- data/ext/boost/detail/endian.hpp +4 -2
- data/ext/boost/detail/fenv.hpp +74 -0
- data/ext/boost/detail/sp_typeinfo.hpp +6 -0
- data/ext/boost/exception/detail/clone_current_exception.hpp +47 -0
- data/ext/boost/exception/detail/exception_ptr.hpp +194 -122
- data/ext/boost/exception/detail/type_info.hpp +3 -3
- data/ext/boost/exception/diagnostic_information.hpp +37 -21
- data/ext/boost/exception/exception.hpp +21 -1
- data/ext/boost/exception/info.hpp +0 -1
- data/ext/boost/function.hpp +2 -2
- data/ext/boost/function/function_base.hpp +15 -9
- data/ext/boost/function/function_template.hpp +26 -48
- data/ext/boost/integer_fwd.hpp +0 -16
- data/ext/boost/integer_traits.hpp +2 -2
- data/ext/boost/iterator.hpp +1 -1
- data/ext/boost/iterator/iterator_adaptor.hpp +1 -7
- data/ext/boost/iterator/iterator_facade.hpp +13 -13
- data/ext/boost/iterator/transform_iterator.hpp +5 -20
- data/ext/boost/lexical_cast.hpp +1655 -673
- data/ext/boost/math/policies/policy.hpp +982 -0
- data/ext/boost/math/special_functions/detail/fp_traits.hpp +570 -0
- data/ext/boost/math/special_functions/detail/round_fwd.hpp +80 -0
- data/ext/boost/math/special_functions/fpclassify.hpp +533 -0
- data/ext/boost/math/special_functions/math_fwd.hpp +1070 -0
- data/ext/boost/math/special_functions/sign.hpp +145 -0
- data/ext/boost/math/tools/config.hpp +321 -0
- data/ext/boost/math/tools/promotion.hpp +150 -0
- data/ext/boost/math/tools/real_cast.hpp +29 -0
- data/ext/boost/math/tools/user.hpp +97 -0
- data/ext/boost/move/move.hpp +1222 -0
- data/ext/boost/mpl/O1_size.hpp +40 -0
- data/ext/boost/mpl/O1_size_fwd.hpp +24 -0
- data/ext/boost/mpl/advance.hpp +76 -0
- data/ext/boost/mpl/advance_fwd.hpp +28 -0
- data/ext/boost/mpl/at.hpp +52 -0
- data/ext/boost/mpl/at_fwd.hpp +24 -0
- data/ext/boost/mpl/aux_/O1_size_impl.hpp +87 -0
- data/ext/boost/mpl/aux_/advance_backward.hpp +128 -0
- data/ext/boost/mpl/aux_/advance_forward.hpp +127 -0
- data/ext/boost/mpl/aux_/arithmetic_op.hpp +92 -0
- data/ext/boost/mpl/aux_/at_impl.hpp +45 -0
- data/ext/boost/mpl/aux_/begin_end_impl.hpp +101 -0
- data/ext/boost/mpl/aux_/clear_impl.hpp +35 -0
- data/ext/boost/mpl/aux_/comparison_op.hpp +83 -0
- data/ext/boost/mpl/aux_/config/forwarding.hpp +27 -0
- data/ext/boost/mpl/aux_/config/typeof.hpp +38 -0
- data/ext/boost/mpl/aux_/contains_impl.hpp +61 -0
- data/ext/boost/mpl/aux_/find_if_pred.hpp +31 -0
- data/ext/boost/mpl/aux_/fold_impl.hpp +43 -0
- data/ext/boost/mpl/aux_/has_begin.hpp +23 -0
- data/ext/boost/mpl/aux_/has_size.hpp +23 -0
- data/ext/boost/mpl/aux_/has_tag.hpp +23 -0
- data/ext/boost/mpl/aux_/inserter_algorithm.hpp +159 -0
- data/ext/boost/mpl/aux_/is_msvc_eti_arg.hpp +64 -0
- data/ext/boost/mpl/aux_/iter_apply.hpp +47 -0
- data/ext/boost/mpl/aux_/iter_fold_if_impl.hpp +210 -0
- data/ext/boost/mpl/aux_/iter_fold_impl.hpp +42 -0
- data/ext/boost/mpl/aux_/lambda_spec.hpp +49 -0
- data/ext/boost/mpl/aux_/largest_int.hpp +63 -0
- data/ext/boost/mpl/aux_/msvc_eti_base.hpp +77 -0
- data/ext/boost/mpl/aux_/msvc_type.hpp +62 -0
- data/ext/boost/mpl/aux_/numeric_cast_utils.hpp +77 -0
- data/ext/boost/mpl/aux_/numeric_op.hpp +315 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp +97 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp +97 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp +94 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp +180 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/greater.hpp +94 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp +94 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp +133 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp +180 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/less.hpp +94 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp +94 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/list.hpp +323 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/minus.hpp +146 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp +94 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/plus.hpp +146 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp +231 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/times.hpp +146 -0
- data/ext/boost/mpl/aux_/preprocessed/gcc/vector.hpp +323 -0
- data/ext/boost/mpl/aux_/preprocessor/default_params.hpp +67 -0
- data/ext/boost/mpl/aux_/push_back_impl.hpp +70 -0
- data/ext/boost/mpl/aux_/push_front_impl.hpp +71 -0
- data/ext/boost/mpl/aux_/reverse_fold_impl.hpp +44 -0
- data/ext/boost/mpl/aux_/size_impl.hpp +52 -0
- data/ext/boost/mpl/aux_/traits_lambda_spec.hpp +63 -0
- data/ext/boost/mpl/back_fwd.hpp +24 -0
- data/ext/boost/mpl/back_inserter.hpp +34 -0
- data/ext/boost/mpl/begin_end.hpp +57 -0
- data/ext/boost/mpl/begin_end_fwd.hpp +27 -0
- data/ext/boost/mpl/clear.hpp +39 -0
- data/ext/boost/mpl/clear_fwd.hpp +24 -0
- data/ext/boost/mpl/comparison.hpp +24 -0
- data/ext/boost/mpl/contains.hpp +41 -0
- data/ext/boost/mpl/contains_fwd.hpp +25 -0
- data/ext/boost/mpl/deref.hpp +41 -0
- data/ext/boost/mpl/distance.hpp +78 -0
- data/ext/boost/mpl/distance_fwd.hpp +28 -0
- data/ext/boost/mpl/empty_fwd.hpp +24 -0
- data/ext/boost/mpl/equal_to.hpp +21 -0
- data/ext/boost/mpl/find.hpp +38 -0
- data/ext/boost/mpl/find_if.hpp +50 -0
- data/ext/boost/mpl/fold.hpp +48 -0
- data/ext/boost/mpl/front_fwd.hpp +24 -0
- data/ext/boost/mpl/front_inserter.hpp +33 -0
- data/ext/boost/mpl/greater.hpp +21 -0
- data/ext/boost/mpl/greater_equal.hpp +21 -0
- data/ext/boost/mpl/inserter.hpp +32 -0
- data/ext/boost/mpl/iter_fold.hpp +49 -0
- data/ext/boost/mpl/iter_fold_if.hpp +117 -0
- data/ext/boost/mpl/iterator_range.hpp +42 -0
- data/ext/boost/mpl/iterator_tags.hpp +27 -0
- data/ext/boost/mpl/less.hpp +21 -0
- data/ext/boost/mpl/less_equal.hpp +21 -0
- data/ext/boost/mpl/limits/list.hpp +21 -0
- data/ext/boost/mpl/limits/vector.hpp +21 -0
- data/ext/boost/mpl/list.hpp +57 -0
- data/ext/boost/mpl/list/aux_/O1_size.hpp +33 -0
- data/ext/boost/mpl/list/aux_/begin_end.hpp +44 -0
- data/ext/boost/mpl/list/aux_/clear.hpp +34 -0
- data/ext/boost/mpl/list/aux_/empty.hpp +34 -0
- data/ext/boost/mpl/list/aux_/front.hpp +33 -0
- data/ext/boost/mpl/list/aux_/include_preprocessed.hpp +35 -0
- data/ext/boost/mpl/list/aux_/item.hpp +55 -0
- data/ext/boost/mpl/list/aux_/iterator.hpp +76 -0
- data/ext/boost/mpl/list/aux_/pop_front.hpp +34 -0
- data/ext/boost/mpl/list/aux_/preprocessed/plain/list10.hpp +149 -0
- data/ext/boost/mpl/list/aux_/preprocessed/plain/list20.hpp +169 -0
- data/ext/boost/mpl/list/aux_/push_back.hpp +36 -0
- data/ext/boost/mpl/list/aux_/push_front.hpp +39 -0
- data/ext/boost/mpl/list/aux_/size.hpp +33 -0
- data/ext/boost/mpl/list/aux_/tag.hpp +24 -0
- data/ext/boost/mpl/list/list0.hpp +42 -0
- data/ext/boost/mpl/list/list10.hpp +43 -0
- data/ext/boost/mpl/list/list20.hpp +43 -0
- data/ext/boost/mpl/long.hpp +22 -0
- data/ext/boost/mpl/long_fwd.hpp +27 -0
- data/ext/boost/mpl/minus.hpp +21 -0
- data/ext/boost/mpl/multiplies.hpp +53 -0
- data/ext/boost/mpl/negate.hpp +81 -0
- data/ext/boost/mpl/not_equal_to.hpp +21 -0
- data/ext/boost/mpl/numeric_cast.hpp +41 -0
- data/ext/boost/mpl/pair.hpp +70 -0
- data/ext/boost/mpl/plus.hpp +21 -0
- data/ext/boost/mpl/pop_back_fwd.hpp +24 -0
- data/ext/boost/mpl/pop_front_fwd.hpp +24 -0
- data/ext/boost/mpl/prior.hpp +19 -0
- data/ext/boost/mpl/push_back.hpp +53 -0
- data/ext/boost/mpl/push_back_fwd.hpp +24 -0
- data/ext/boost/mpl/push_front.hpp +52 -0
- data/ext/boost/mpl/push_front_fwd.hpp +24 -0
- data/ext/boost/mpl/remove_if.hpp +83 -0
- data/ext/boost/mpl/reverse_fold.hpp +50 -0
- data/ext/boost/mpl/same_as.hpp +55 -0
- data/ext/boost/mpl/sequence_tag.hpp +124 -0
- data/ext/boost/mpl/sequence_tag_fwd.hpp +26 -0
- data/ext/boost/mpl/size.hpp +42 -0
- data/ext/boost/mpl/size_fwd.hpp +24 -0
- data/ext/boost/mpl/tag.hpp +52 -0
- data/ext/boost/mpl/times.hpp +21 -0
- data/ext/boost/mpl/vector.hpp +57 -0
- data/ext/boost/mpl/vector/aux_/O1_size.hpp +56 -0
- data/ext/boost/mpl/vector/aux_/at.hpp +116 -0
- data/ext/boost/mpl/vector/aux_/back.hpp +59 -0
- data/ext/boost/mpl/vector/aux_/begin_end.hpp +49 -0
- data/ext/boost/mpl/vector/aux_/clear.hpp +55 -0
- data/ext/boost/mpl/vector/aux_/empty.hpp +68 -0
- data/ext/boost/mpl/vector/aux_/front.hpp +56 -0
- data/ext/boost/mpl/vector/aux_/include_preprocessed.hpp +55 -0
- data/ext/boost/mpl/vector/aux_/item.hpp +103 -0
- data/ext/boost/mpl/vector/aux_/iterator.hpp +130 -0
- data/ext/boost/mpl/vector/aux_/pop_back.hpp +40 -0
- data/ext/boost/mpl/vector/aux_/pop_front.hpp +40 -0
- data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp +829 -0
- data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp +1144 -0
- data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp +139 -0
- data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp +159 -0
- data/ext/boost/mpl/vector/aux_/push_back.hpp +40 -0
- data/ext/boost/mpl/vector/aux_/push_front.hpp +40 -0
- data/ext/boost/mpl/vector/aux_/size.hpp +49 -0
- data/ext/boost/mpl/vector/aux_/tag.hpp +32 -0
- data/ext/boost/mpl/vector/aux_/vector0.hpp +52 -0
- data/ext/boost/mpl/vector/vector0.hpp +34 -0
- data/ext/boost/mpl/vector/vector10.hpp +45 -0
- data/ext/boost/mpl/vector/vector20.hpp +45 -0
- data/ext/boost/none.hpp +1 -1
- data/ext/boost/numeric/conversion/bounds.hpp +24 -0
- data/ext/boost/numeric/conversion/cast.hpp +61 -0
- data/ext/boost/numeric/conversion/conversion_traits.hpp +39 -0
- data/ext/boost/numeric/conversion/converter.hpp +68 -0
- data/ext/boost/numeric/conversion/converter_policies.hpp +186 -0
- data/ext/boost/numeric/conversion/detail/bounds.hpp +58 -0
- data/ext/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
- data/ext/boost/numeric/conversion/detail/converter.hpp +602 -0
- data/ext/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
- data/ext/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
- data/ext/boost/numeric/conversion/detail/meta.hpp +120 -0
- data/ext/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
- data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
- data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
- data/ext/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
- data/ext/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
- data/ext/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
- data/ext/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
- data/ext/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
- data/ext/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
- data/ext/boost/operators.hpp +3 -1
- data/ext/boost/optional/optional.hpp +146 -79
- data/ext/boost/optional/optional_fwd.hpp +8 -1
- data/ext/boost/preprocessor/cat.hpp +2 -2
- data/ext/boost/preprocessor/config/config.hpp +39 -4
- data/ext/boost/preprocessor/facilities/intercept.hpp +277 -0
- data/ext/boost/preprocessor/facilities/overload.hpp +25 -0
- data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +3 -3
- data/ext/boost/preprocessor/iteration/iterate.hpp +3 -3
- data/ext/boost/preprocessor/punctuation/paren.hpp +23 -0
- data/ext/boost/preprocessor/repetition/enum_shifted_params.hpp +44 -0
- data/ext/boost/preprocessor/seq/cat.hpp +5 -4
- data/ext/boost/preprocessor/seq/size.hpp +0 -1
- data/ext/boost/preprocessor/tuple/eat.hpp +83 -34
- data/ext/boost/preprocessor/tuple/elem.hpp +161 -355
- data/ext/boost/preprocessor/tuple/rem.hpp +110 -48
- data/ext/boost/preprocessor/tuple/to_list.hpp +90 -36
- data/ext/boost/preprocessor/variadic/elem.hpp +94 -0
- data/ext/boost/preprocessor/variadic/size.hpp +30 -0
- data/ext/boost/range/begin.hpp +17 -6
- data/ext/boost/range/concepts.hpp +37 -2
- data/ext/boost/range/detail/safe_bool.hpp +72 -0
- data/ext/boost/range/end.hpp +14 -9
- data/ext/boost/range/iterator_range_core.hpp +120 -12
- data/ext/boost/range/size.hpp +21 -5
- data/ext/boost/smart_ptr/detail/shared_count.hpp +88 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +3 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +142 -0
- data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +9 -0
- data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +10 -2
- data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +5 -1
- data/ext/boost/smart_ptr/detail/spinlock.hpp +4 -1
- data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +20 -3
- data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +4 -0
- data/ext/boost/smart_ptr/make_shared.hpp +591 -22
- data/ext/boost/smart_ptr/shared_array.hpp +29 -1
- data/ext/boost/smart_ptr/shared_ptr.hpp +29 -13
- data/ext/boost/smart_ptr/weak_ptr.hpp +24 -12
- data/ext/boost/src/pthread/once.cpp +9 -7
- data/ext/boost/src/pthread/thread.cpp +32 -28
- data/ext/boost/src/pthread/timeconv.inl +4 -5
- data/ext/boost/src/tss_null.cpp +5 -1
- data/ext/boost/static_assert.hpp +8 -2
- data/ext/boost/thread/detail/config.hpp +19 -4
- data/ext/boost/thread/detail/move.hpp +11 -5
- data/ext/boost/thread/detail/thread.hpp +59 -43
- data/ext/boost/thread/exceptions.hpp +9 -9
- data/ext/boost/thread/future.hpp +150 -82
- data/ext/boost/thread/locks.hpp +101 -60
- data/ext/boost/thread/pthread/condition_variable.hpp +79 -32
- data/ext/boost/thread/pthread/condition_variable_fwd.hpp +12 -3
- data/ext/boost/thread/pthread/mutex.hpp +17 -14
- data/ext/boost/thread/pthread/once.hpp +3 -4
- data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +12 -2
- data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -19
- data/ext/boost/thread/pthread/shared_mutex.hpp +13 -13
- data/ext/boost/thread/pthread/thread_data.hpp +40 -12
- data/ext/boost/thread/thread_time.hpp +5 -0
- data/ext/boost/throw_exception.hpp +1 -1
- data/ext/boost/token_functions.hpp +34 -10
- data/ext/boost/type_traits/add_rvalue_reference.hpp +66 -0
- data/ext/boost/type_traits/alignment_of.hpp +1 -1
- data/ext/boost/type_traits/detail/bool_trait_def.hpp +26 -3
- data/ext/boost/type_traits/detail/bool_trait_undef.hpp +3 -2
- data/ext/boost/type_traits/detail/cv_traits_impl.hpp +1 -1
- data/ext/boost/type_traits/detail/size_t_trait_def.hpp +6 -4
- data/ext/boost/type_traits/detail/type_trait_def.hpp +8 -2
- data/ext/boost/type_traits/function_traits.hpp +1 -1
- data/ext/boost/type_traits/has_nothrow_constructor.hpp +53 -0
- data/ext/boost/type_traits/has_nothrow_copy.hpp +19 -5
- data/ext/boost/type_traits/has_trivial_constructor.hpp +51 -0
- data/ext/boost/type_traits/has_trivial_copy.hpp +20 -5
- data/ext/boost/type_traits/has_trivial_destructor.hpp +12 -5
- data/ext/boost/type_traits/intrinsics.hpp +119 -71
- data/ext/boost/type_traits/is_const.hpp +5 -5
- data/ext/boost/type_traits/is_convertible.hpp +14 -13
- data/ext/boost/type_traits/is_enum.hpp +1 -1
- data/ext/boost/type_traits/is_floating_point.hpp +27 -0
- data/ext/boost/type_traits/is_function.hpp +3 -3
- data/ext/boost/type_traits/is_fundamental.hpp +1 -1
- data/ext/boost/type_traits/is_member_function_pointer.hpp +2 -2
- data/ext/boost/type_traits/is_member_pointer.hpp +2 -2
- data/ext/boost/type_traits/is_pod.hpp +11 -3
- data/ext/boost/type_traits/is_pointer.hpp +2 -2
- data/ext/boost/type_traits/is_signed.hpp +8 -3
- data/ext/boost/type_traits/is_union.hpp +8 -0
- data/ext/boost/type_traits/is_unsigned.hpp +9 -4
- data/ext/boost/type_traits/is_volatile.hpp +5 -5
- data/ext/boost/type_traits/remove_cv.hpp +4 -3
- data/ext/boost/type_traits/remove_pointer.hpp +51 -2
- data/ext/boost/type_traits/remove_reference.hpp +2 -2
- data/ext/boost/type_traits/type_with_alignment.hpp +8 -2
- data/ext/boost/utility/declval.hpp +44 -0
- data/ext/boost/utility/detail/in_place_factory_prefix.hpp +36 -0
- data/ext/boost/utility/detail/in_place_factory_suffix.hpp +23 -0
- data/ext/boost/utility/detail/result_of_iterate.hpp +142 -0
- data/ext/boost/utility/in_place_factory.hpp +88 -0
- data/ext/boost/utility/result_of.hpp +103 -0
- data/ext/boost/utility/swap.hpp +55 -0
- data/ext/common/AnsiColorConstants.h +36 -0
- data/ext/common/ApplicationPool2/Common.h +87 -0
- data/ext/common/ApplicationPool2/ComponentInfo.h +53 -0
- data/ext/common/ApplicationPool2/Group.h +648 -0
- data/ext/common/ApplicationPool2/Implementation.cpp +580 -0
- data/ext/common/ApplicationPool2/Options.h +576 -0
- data/ext/common/ApplicationPool2/PipeWatcher.h +61 -0
- data/ext/common/ApplicationPool2/Pool.h +1181 -0
- data/ext/common/ApplicationPool2/Process.h +425 -0
- data/ext/common/ApplicationPool2/README.md +96 -0
- data/ext/common/ApplicationPool2/Session.h +158 -0
- data/ext/common/ApplicationPool2/Socket.h +246 -0
- data/ext/common/ApplicationPool2/Spawner.h +2212 -0
- data/ext/common/ApplicationPool2/SuperGroup.h +749 -0
- data/ext/common/BackgroundEventLoop.cpp +129 -0
- data/ext/common/BackgroundEventLoop.h +61 -0
- data/ext/common/Constants.h +3 -1
- data/ext/common/EventedBufferedInput.h +331 -0
- data/ext/common/EventedMessageServer.h +17 -34
- data/ext/common/EventedServer.h +2 -2
- data/ext/common/Exceptions.h +71 -19
- data/ext/common/FileDescriptor.h +8 -6
- data/ext/common/HttpConstants.h +167 -0
- data/ext/common/IniFile.h +24 -0
- data/ext/common/Logging.h +62 -849
- data/ext/common/MessageReadersWriters.h +19 -0
- data/ext/common/MessageServer.h +11 -14
- data/ext/common/MultiLibeio.cpp +198 -0
- data/ext/common/MultiLibeio.h +67 -0
- data/ext/common/ResourceLocator.h +24 -41
- data/ext/common/SafeLibev.h +186 -14
- data/ext/common/StaticString.h +23 -3
- data/ext/common/UnionStation.h +972 -0
- data/ext/common/Utils.cpp +168 -24
- data/ext/common/Utils.h +25 -3
- data/ext/common/Utils/CachedFileStat.hpp +4 -3
- data/ext/common/Utils/FileChangeChecker.h +2 -2
- data/ext/common/Utils/HashMap.h +50 -0
- data/ext/common/Utils/IOUtils.cpp +229 -68
- data/ext/common/Utils/IOUtils.h +134 -3
- data/ext/common/Utils/Lock.h +28 -0
- data/ext/common/Utils/MemoryBarrier.h +52 -0
- data/ext/common/Utils/PriorityQueue.h +54 -0
- data/ext/common/Utils/ProcessMetricsCollector.h +9 -11
- data/ext/common/Utils/ScopeGuard.h +50 -1
- data/ext/common/Utils/SmallVector.h +653 -0
- data/ext/common/Utils/StrIntUtils.cpp +26 -2
- data/ext/common/Utils/StrIntUtils.h +18 -2
- data/ext/common/Utils/StringMap.h +125 -8
- data/ext/common/Utils/Template.h +212 -0
- data/ext/common/Utils/fib.c +699 -0
- data/ext/common/Utils/fib.h +101 -0
- data/ext/common/Utils/fibpriv.h +67 -0
- data/ext/common/Utils/json-forwards.h +249 -0
- data/ext/common/Utils/json.h +1855 -0
- data/ext/common/Utils/jsoncpp.cpp +4230 -0
- data/ext/common/agents/Base.cpp +1126 -0
- data/ext/common/{AgentBase.h → agents/Base.h} +5 -1
- data/ext/common/agents/EnvPrinter.c +16 -0
- data/ext/common/agents/HelperAgent/AgentOptions.h +81 -0
- data/ext/common/{HelperAgent → agents/HelperAgent}/BacktracesServer.h +3 -2
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +732 -0
- data/ext/common/agents/HelperAgent/Main.cpp +497 -0
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +283 -0
- data/ext/common/agents/HelperAgent/RequestHandler.h +2139 -0
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +451 -0
- data/ext/common/{LoggingAgent → agents/LoggingAgent}/DataStoreId.h +1 -1
- data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.cpp +1 -1
- data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.h +0 -0
- data/ext/common/{LoggingAgent → agents/LoggingAgent}/LoggingServer.h +18 -16
- data/ext/common/{LoggingAgent → agents/LoggingAgent}/Main.cpp +15 -13
- data/ext/common/{LoggingAgent → agents/LoggingAgent}/RemoteSender.h +6 -6
- data/ext/common/agents/SpawnPreparer.cpp +127 -0
- data/ext/common/{Watchdog.cpp → agents/Watchdog/Main.cpp} +63 -25
- data/ext/libeio/Changes +72 -0
- data/ext/{google/COPYING → libeio/LICENSE} +17 -9
- data/ext/libeio/Makefile.am +15 -0
- data/ext/libeio/Makefile.in +694 -0
- data/ext/libeio/aclocal.m4 +9418 -0
- data/ext/libeio/autogen.sh +3 -0
- data/ext/libeio/config.guess +1501 -0
- data/ext/libeio/config.h.in +136 -0
- data/ext/libeio/config.sub +1705 -0
- data/ext/libeio/configure +14822 -0
- data/ext/libeio/configure.ac +22 -0
- data/ext/libeio/demo.c +194 -0
- data/ext/libeio/ecb.h +457 -0
- data/ext/libeio/eio.c +2816 -0
- data/ext/libeio/eio.h +411 -0
- data/ext/libeio/install-sh +520 -0
- data/ext/libeio/libeio.m4 +211 -0
- data/ext/libeio/ltmain.sh +9636 -0
- data/ext/libeio/missing +376 -0
- data/ext/libeio/xthread.h +166 -0
- data/ext/libev/Changes +125 -7
- data/ext/libev/Makefile.am +5 -3
- data/ext/libev/Makefile.in +209 -120
- data/ext/libev/aclocal.m4 +6027 -4619
- data/ext/libev/autogen.sh +1 -4
- data/ext/libev/config.h.in +11 -7
- data/ext/libev/configure +7312 -14993
- data/ext/libev/configure.ac +12 -5
- data/ext/libev/depcomp +630 -0
- data/ext/libev/ev++.h +48 -32
- data/ext/libev/ev.c +1173 -391
- data/ext/libev/ev.h +315 -181
- data/ext/libev/ev_epoll.c +66 -15
- data/ext/libev/ev_kqueue.c +20 -18
- data/ext/libev/ev_poll.c +27 -23
- data/ext/libev/ev_port.c +39 -19
- data/ext/libev/ev_select.c +23 -17
- data/ext/libev/ev_vars.h +25 -8
- data/ext/libev/ev_win32.c +6 -6
- data/ext/libev/ev_wrap.h +22 -2
- data/ext/libev/event.c +18 -17
- data/ext/libev/event.h +16 -4
- data/ext/libev/libev.m4 +10 -6
- data/ext/libev/ltmain.sh +7353 -5811
- data/ext/nginx/Configuration.c +74 -42
- data/ext/nginx/Configuration.h +3 -5
- data/ext/nginx/ContentHandler.c +26 -83
- data/ext/nginx/ContentHandler.h +1 -1
- data/ext/nginx/config +13 -9
- data/ext/nginx/ngx_http_passenger_module.c +3 -7
- data/ext/oxt/detail/backtrace_enabled.hpp +5 -102
- data/ext/oxt/detail/context.hpp +90 -0
- data/ext/oxt/detail/spin_lock_darwin.hpp +4 -0
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +4 -0
- data/ext/oxt/detail/spin_lock_pthreads.hpp +14 -0
- data/ext/oxt/detail/tracable_exception_enabled.hpp +2 -2
- data/ext/oxt/dynamic_thread_group.hpp +27 -1
- data/ext/oxt/implementation.cpp +415 -0
- data/ext/oxt/{thread.cpp → initialize.hpp} +13 -6
- data/ext/oxt/macros.hpp +32 -1
- data/ext/oxt/spin_lock.hpp +6 -11
- data/ext/oxt/system_calls.cpp +204 -16
- data/ext/oxt/system_calls.hpp +85 -45
- data/ext/oxt/thread.hpp +13 -117
- data/ext/ruby/passenger_native_support.c +82 -237
- data/helper-scripts/backtrace-sanitizer.rb +114 -0
- data/helper-scripts/classic-rails-loader.rb +135 -0
- data/helper-scripts/classic-rails-preloader.rb +161 -0
- data/helper-scripts/node-loader.js +314 -0
- data/helper-scripts/rack-loader.rb +104 -0
- data/helper-scripts/rack-preloader.rb +132 -0
- data/helper-scripts/wsgi-loader.py +231 -0
- data/helper-scripts/wsgi-preloader.py +1 -0
- data/lib/phusion_passenger.rb +159 -61
- data/lib/phusion_passenger/abstract_installer.rb +182 -87
- data/lib/phusion_passenger/admin_tools/server_instance.rb +25 -19
- data/lib/phusion_passenger/analytics_logger.rb +5 -4
- data/lib/phusion_passenger/classic_rails/{request_handler.rb → thread_handler_extension.rb} +4 -40
- data/lib/phusion_passenger/classic_rails_extensions/init.rb +5 -3
- data/lib/phusion_passenger/common_library.rb +441 -0
- data/lib/phusion_passenger/console_text_template.rb +4 -16
- data/lib/phusion_passenger/constants.rb +1 -8
- data/lib/phusion_passenger/debug_logging.rb +5 -2
- data/lib/phusion_passenger/dependencies.rb +51 -13
- data/lib/phusion_passenger/loader_shared_helpers.rb +318 -0
- data/lib/phusion_passenger/message_channel.rb +3 -47
- data/lib/phusion_passenger/message_client.rb +2 -2
- data/lib/phusion_passenger/native_support.rb +36 -15
- data/lib/phusion_passenger/packaging.rb +8 -11
- data/lib/phusion_passenger/platform_info.rb +25 -17
- data/lib/phusion_passenger/platform_info/apache.rb +10 -7
- data/lib/phusion_passenger/platform_info/binary_compatibility.rb +10 -30
- data/lib/phusion_passenger/platform_info/compiler.rb +93 -34
- data/lib/phusion_passenger/platform_info/ruby.rb +37 -97
- data/lib/phusion_passenger/preloader_shared_helpers.rb +121 -0
- data/lib/phusion_passenger/public_api.rb +1 -4
- data/lib/phusion_passenger/rack/{request_handler.rb → thread_handler_extension.rb} +14 -63
- data/lib/phusion_passenger/rails3_extensions/init.rb +9 -8
- data/lib/phusion_passenger/request_handler.rb +500 -0
- data/lib/phusion_passenger/request_handler/thread_handler.rb +360 -0
- data/lib/phusion_passenger/ruby_core_enhancements.rb +142 -0
- data/lib/phusion_passenger/standalone/command.rb +36 -15
- data/lib/phusion_passenger/standalone/package_runtime_command.rb +16 -8
- data/lib/phusion_passenger/standalone/runtime_installer.rb +169 -72
- data/lib/phusion_passenger/standalone/start_command.rb +44 -39
- data/lib/phusion_passenger/standalone/utils.rb +5 -5
- data/lib/phusion_passenger/utils.rb +35 -914
- data/lib/phusion_passenger/utils/ansi_colors.rb +59 -0
- data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
- data/lib/phusion_passenger/utils/robust_interruption.rb +134 -0
- data/lib/phusion_passenger/utils/tee_input.rb +174 -0
- data/lib/phusion_passenger/utils/tmpio.rb +33 -0
- data/lib/phusion_passenger/utils/unseekable_socket.rb +6 -0
- data/resources/mime.types +5 -1
- data/{lib/phusion_passenger/templates → resources}/standalone_default_root/index.html +0 -0
- data/{lib/phusion_passenger → resources}/templates/apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/apache2/config_snippets.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/apache2/deployment_example.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/apache2/run_installer_as_root.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/apache2/welcome.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/error_layout.css +6 -0
- data/resources/templates/error_layout.html.template +89 -0
- data/resources/templates/general_error.html.template +1 -0
- data/resources/templates/general_error_with_html.html.template +1 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/ask_for_extra_configure_flags.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/cannot_write_to_dir.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets_inserted.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/confirm_extra_configure_flags.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/deployment_example.txt.erb +0 -0
- data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +8 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_downloaded.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_extracted.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/query_download_and_install.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/run_installer_as_root.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/nginx/welcome.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/standalone/cannot_write_to_dir.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/standalone/config.erb +26 -5
- data/{lib/phusion_passenger → resources}/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/standalone/run_installer_as_root.txt.erb +0 -0
- data/{lib/phusion_passenger → resources}/templates/standalone/welcome.txt.erb +0 -0
- data/resources/templates/undisclosed_error.html.template +25 -0
- data/test/config.json.example +42 -0
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +86 -0
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +44 -0
- data/test/cxx/ApplicationPool2/PoolTest.cpp +1234 -0
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +131 -0
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +229 -0
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +744 -0
- data/test/cxx/BufferedIOTest.cpp +7 -7
- data/test/cxx/CxxTestMain.cpp +65 -2
- data/test/cxx/FileBackedPipeTest.cpp +626 -0
- data/test/cxx/FileChangeCheckerTest.cpp +20 -18
- data/test/cxx/FilterSupportTest.cpp +5 -5
- data/test/cxx/IOUtilsTest.cpp +11 -4
- data/test/cxx/MessageReadersWritersTest.cpp +1 -1
- data/test/cxx/MessageServerTest.cpp +31 -30
- data/test/cxx/RequestHandlerTest.cpp +777 -0
- data/test/cxx/ScgiRequestParserTest.cpp +36 -16
- data/test/cxx/ServerInstanceDirTest.cpp +1 -1
- data/test/cxx/StringMapTest.cpp +61 -0
- data/test/cxx/TemplateTest.cpp +118 -0
- data/test/cxx/TestSupport.cpp +25 -68
- data/test/cxx/TestSupport.h +81 -41
- data/test/cxx/{LoggingTest.cpp → UnionStationTest.cpp} +79 -74
- data/test/cxx/UtilsTest.cpp +59 -5
- data/test/integration_tests/apache2_tests.rb +2 -2
- data/test/integration_tests/nginx_tests.rb +1 -1
- data/test/integration_tests/spec_helper.rb +7 -5
- data/test/oxt/oxt_test_main.cpp +2 -0
- data/test/oxt/syscall_interruption_test.cpp +1 -0
- data/test/ruby/classic_rails/loader_spec.rb +48 -0
- data/test/ruby/classic_rails/preloader_spec.rb +54 -0
- data/test/ruby/rack/loader_spec.rb +62 -0
- data/test/ruby/rack/preloader_spec.rb +74 -0
- data/test/ruby/{abstract_request_handler_spec.rb → request_handler_spec.rb} +31 -68
- data/test/ruby/shared/loader_spec.rb +241 -0
- data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +141 -182
- data/test/ruby/shared/ruby_loader_spec.rb +55 -0
- data/test/ruby/spec_helper.rb +8 -53
- data/test/ruby/utils/file_system_watcher_spec.rb +9 -1
- data/test/ruby/utils_spec.rb +10 -683
- data/test/stub/rack/config.ru +28 -3
- data/test/stub/rack/start.rb +47 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/Rakefile +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/application_controller.rb +0 -2
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_1.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_2.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/foo_controller.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/helpers/application_helper.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/boot.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/database.yml +3 -3
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environment.rb +5 -2
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/development.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/production.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/staging.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/inflections.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/mime_types.rb +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/routes.rb +1 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/about +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/console +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/dbconsole +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/destroy +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/generate +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/benchmarker +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/profiler +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/request +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/plugin +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/inspector +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/reaper +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/spawner +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/runner +0 -0
- data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/server +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/Gemfile +0 -0
- data/test/stub/rails3.0/Gemfile.lock +80 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/Rakefile +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/controllers/application_controller.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/helpers/application_helper.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/views/layouts/application.html.erb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config.ru +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/application.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/boot.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/database.yml +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environment.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/development.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/production.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/test.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/backtrace_silencers.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/inflections.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/mime_types.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/passenger.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/secret_token.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/session_store.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/locales/en.yml +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/routes.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/db/seeds.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/doc/README_FOR_APP +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/404.html +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/422.html +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/500.html +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/favicon.ico +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/index.html +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/robots.txt +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/script/rails +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/performance/browsing_test.rb +0 -0
- data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/test_helper.rb +0 -0
- data/test/stub/start_error.pl +24 -0
- data/test/stub/wsgi/passenger_wsgi.py +71 -3
- data/test/support/apache2_controller.rb +2 -2
- data/test/support/placebo-preloader.rb +88 -0
- data/test/support/test_helper.rb +1 -14
- data/test/tut/tut.h +11 -4
- metadata +590 -326
- data.tar.gz.asc +0 -12
- data/PACKAGING.TXT +0 -25
- data/build/config.rb +0 -46
- data/ext/apache2/HelperAgent.cpp +0 -364
- data/ext/boost/call_traits.hpp +0 -24
- data/ext/boost/detail/call_traits.hpp +0 -164
- data/ext/common/AbstractSpawnManager.h +0 -110
- data/ext/common/AgentBase.cpp +0 -432
- data/ext/common/ApplicationPool/Client.h +0 -788
- data/ext/common/ApplicationPool/Interface.h +0 -295
- data/ext/common/ApplicationPool/Pool.h +0 -1327
- data/ext/common/ApplicationPool/Server.h +0 -479
- data/ext/common/MessageChannel.h +0 -494
- data/ext/common/PoolOptions.h +0 -518
- data/ext/common/Process.h +0 -253
- data/ext/common/Session.h +0 -436
- data/ext/common/SpawnManager.h +0 -611
- data/ext/google/ChangeLog +0 -167
- data/ext/google/dense_hash_map +0 -310
- data/ext/google/dense_hash_set +0 -287
- data/ext/google/sparse_hash_map +0 -294
- data/ext/google/sparse_hash_set +0 -275
- data/ext/google/sparsehash/densehashtable.h +0 -1062
- data/ext/google/sparsehash/sparseconfig.h +0 -55
- data/ext/google/sparsehash/sparsehashtable.h +0 -1015
- data/ext/google/sparsetable +0 -1468
- data/ext/google/type_traits.h +0 -250
- data/ext/nginx/HelperAgent.cpp +0 -1355
- data/ext/nginx/ScgiRequestParser.h +0 -375
- data/ext/oxt/backtrace.cpp +0 -185
- data/ext/oxt/tracable_exception.cpp +0 -89
- data/helper-scripts/passenger-spawn-server +0 -106
- data/lib/phusion_passenger/abstract_request_handler.rb +0 -766
- data/lib/phusion_passenger/abstract_server.rb +0 -372
- data/lib/phusion_passenger/abstract_server_collection.rb +0 -335
- data/lib/phusion_passenger/app_process.rb +0 -174
- data/lib/phusion_passenger/classic_rails/application_spawner.rb +0 -344
- data/lib/phusion_passenger/classic_rails/framework_spawner.rb +0 -311
- data/lib/phusion_passenger/exceptions.rb +0 -103
- data/lib/phusion_passenger/html_template.rb +0 -107
- data/lib/phusion_passenger/rack/application_spawner.rb +0 -231
- data/lib/phusion_passenger/spawn_manager.rb +0 -359
- data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +0 -38
- data/lib/phusion_passenger/templates/app_init_error.html.erb +0 -64
- data/lib/phusion_passenger/templates/database_error.html.erb +0 -66
- data/lib/phusion_passenger/templates/error_layout.html.erb +0 -39
- data/lib/phusion_passenger/templates/framework_init_error.html.erb +0 -39
- data/lib/phusion_passenger/templates/general_error.html.erb +0 -22
- data/lib/phusion_passenger/templates/load_error.html.erb +0 -46
- data/lib/phusion_passenger/templates/version_not_found.html.erb +0 -34
- data/lib/phusion_passenger/utils/rewindable_input.rb +0 -125
- data/lib/phusion_passenger/wsgi/application_spawner.rb +0 -108
- data/test/config.yml.example +0 -41
- data/test/cxx/ApplicationPool_PoolTest.cpp +0 -33
- data/test/cxx/ApplicationPool_PoolTestCases.cpp +0 -1029
- data/test/cxx/ApplicationPool_ServerTest.cpp +0 -308
- data/test/cxx/ApplicationPool_Server_PoolTest.cpp +0 -80
- data/test/cxx/MessageChannelTest.cpp +0 -557
- data/test/cxx/PoolOptionsTest.cpp +0 -116
- data/test/cxx/SpawnManagerTest.cpp +0 -161
- data/test/ruby/abstract_server_collection_spec.rb +0 -247
- data/test/ruby/abstract_server_spec.rb +0 -61
- data/test/ruby/app_process_spec.rb +0 -43
- data/test/ruby/classic_rails/application_spawner_spec.rb +0 -89
- data/test/ruby/classic_rails/framework_spawner_spec.rb +0 -92
- data/test/ruby/rack/application_spawner_spec.rb +0 -116
- data/test/ruby/shared/abstract_server_spec.rb +0 -23
- data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +0 -38
- data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +0 -19
- data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +0 -15
- data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +0 -27
- data/test/ruby/shared/spawners/preloading_spawner_spec.rb +0 -29
- data/test/ruby/shared/spawners/reload_all_spec.rb +0 -36
- data/test/ruby/shared/spawners/reload_single_spec.rb +0 -52
- data/test/ruby/shared/spawners/spawn_server_spec.rb +0 -28
- data/test/ruby/shared/spawners/spawner_spec.rb +0 -273
- data/test/ruby/shared/utils/pseudo_io_spec.rb +0 -60
- data/test/ruby/spawn_manager_spec.rb +0 -134
- data/test/ruby/wsgi/application_spawner_spec.rb +0 -50
- data/test/stub/message_channel.rb +0 -11
- data/test/stub/message_channel_2.rb +0 -12
- data/test/stub/message_channel_3.rb +0 -19
- data/test/stub/rails_apps/3.0/empty/Gemfile.lock +0 -73
- data/test/stub/spawn_server.rb +0 -22
- metadata.gz.asc +0 -12
@@ -40,14 +40,14 @@ namespace tut {
|
|
40
40
|
TempDir d("test.tmp");
|
41
41
|
touchFile("test.tmp/test.txt");
|
42
42
|
|
43
|
-
|
43
|
+
runShellCommand("chmod a= test.tmp");
|
44
44
|
ensure(!checker.changed("test.tmp/test.txt"));
|
45
45
|
|
46
46
|
// Should still be false.
|
47
47
|
ensure(!checker.changed("test.tmp/test.txt"));
|
48
48
|
|
49
49
|
// Now make it accessible again...
|
50
|
-
|
50
|
+
runShellCommand("chmod u=rwx test.tmp");
|
51
51
|
ensure(checker.changed("test.tmp/test.txt"));
|
52
52
|
}
|
53
53
|
}
|
@@ -90,20 +90,20 @@ namespace tut {
|
|
90
90
|
}
|
91
91
|
|
92
92
|
TEST_METHOD(6) {
|
93
|
-
// File is changed if existed
|
93
|
+
// File is not changed if existed and has now been deleted.
|
94
94
|
FileChangeChecker checker(10);
|
95
95
|
|
96
96
|
touchFile("test.txt");
|
97
97
|
checker.changed("test.txt");
|
98
98
|
unlink("test.txt");
|
99
|
-
ensure("test.txt is considered changed if it has been deleted",
|
100
|
-
checker.changed("test.txt"));
|
99
|
+
ensure("test.txt is not considered changed if it has been deleted",
|
100
|
+
!checker.changed("test.txt"));
|
101
101
|
|
102
102
|
touchFile("test2.txt");
|
103
103
|
checker.changed("test2.txt");
|
104
104
|
unlink("test2.txt");
|
105
|
-
ensure("test2.txt is considered changed if it has been deleted",
|
106
|
-
checker.changed("test2.txt"));
|
105
|
+
ensure("test2.txt is not considered changed if it has been deleted",
|
106
|
+
!checker.changed("test2.txt"));
|
107
107
|
}
|
108
108
|
|
109
109
|
TEST_METHOD(7) {
|
@@ -138,11 +138,11 @@ namespace tut {
|
|
138
138
|
checker.changed("test.tmp/test.txt");
|
139
139
|
|
140
140
|
touchFile("test.tmp/test.txt", 2);
|
141
|
-
|
141
|
+
runShellCommand("chmod a= test.tmp");
|
142
142
|
ensure("First check returns false", !checker.changed("test.tmp/test.txt"));
|
143
143
|
|
144
144
|
// Now make it accessible again...
|
145
|
-
|
145
|
+
runShellCommand("chmod u=rwx test.tmp");
|
146
146
|
ensure("Second check returns true", checker.changed("test.tmp/test.txt"));
|
147
147
|
}
|
148
148
|
}
|
@@ -201,14 +201,14 @@ namespace tut {
|
|
201
201
|
|
202
202
|
FileChangeChecker checker(10);
|
203
203
|
TempDir d("test.tmp");
|
204
|
-
touchFile("test.tmp/test.txt");
|
204
|
+
touchFile("test.tmp/test.txt", 1);
|
205
205
|
|
206
206
|
checker.changed("test.tmp/test.txt");
|
207
|
-
|
208
|
-
|
209
|
-
ensure(!checker.changed("test.tmp/test.txt"));
|
210
|
-
|
211
|
-
ensure(checker.changed("test.tmp/test.txt"));
|
207
|
+
touchFile("test.tmp/test.txt", 2);
|
208
|
+
runShellCommand("chmod a= test.tmp");
|
209
|
+
ensure("(1)", !checker.changed("test.tmp/test.txt"));
|
210
|
+
runShellCommand("chmod u=rwx test.tmp");
|
211
|
+
ensure("(2)", checker.changed("test.tmp/test.txt"));
|
212
212
|
}
|
213
213
|
}
|
214
214
|
|
@@ -228,9 +228,11 @@ namespace tut {
|
|
228
228
|
unlink("test.txt");
|
229
229
|
unlink("test2.txt");
|
230
230
|
unlink("test3.txt");
|
231
|
-
ensure("test2.txt is still in the file list", checker.
|
232
|
-
ensure("
|
233
|
-
ensure("
|
231
|
+
ensure("test2.txt is still in the file list", checker.knows("test2.txt"));
|
232
|
+
ensure("test2.txt is not considered changed", !checker.changed("test2.txt"));
|
233
|
+
ensure("test3.txt is still in the file list", checker.knows("test3.txt"));
|
234
|
+
ensure("test3.txt is not considered changed", !checker.changed("test3.txt"));
|
235
|
+
ensure("test.txt is removed from the file list", !checker.knows("test.txt"));
|
234
236
|
}
|
235
237
|
|
236
238
|
TEST_METHOD(14) {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#include "TestSupport.h"
|
2
|
-
#include "LoggingAgent/FilterSupport.h"
|
2
|
+
#include "agents/LoggingAgent/FilterSupport.h"
|
3
3
|
|
4
4
|
#include <boost/bind.hpp>
|
5
5
|
#include <boost/shared_ptr.hpp>
|
@@ -159,13 +159,13 @@ namespace tut {
|
|
159
159
|
TEST_METHOD(15) {
|
160
160
|
// String begin and end quote characters must match.
|
161
161
|
try {
|
162
|
-
Filter("uri == 'hello world\"");
|
162
|
+
(void) Filter("uri == 'hello world\"");
|
163
163
|
fail("Syntax error expected");
|
164
164
|
} catch (const SyntaxError &) {
|
165
165
|
// Pass.
|
166
166
|
}
|
167
167
|
try {
|
168
|
-
Filter("uri == \"hello world'");
|
168
|
+
(void) Filter("uri == \"hello world'");
|
169
169
|
fail("Syntax error expected");
|
170
170
|
} catch (const SyntaxError &) {
|
171
171
|
// Pass.
|
@@ -177,13 +177,13 @@ namespace tut {
|
|
177
177
|
ctx.uri = "hello world";
|
178
178
|
ensure(Filter("uri =~ %r{hello}").run(ctx));
|
179
179
|
try {
|
180
|
-
Filter("uri =~ /hello}");
|
180
|
+
(void) Filter("uri =~ /hello}");
|
181
181
|
fail("Syntax error expected");
|
182
182
|
} catch (const SyntaxError &) {
|
183
183
|
// Pass.
|
184
184
|
}
|
185
185
|
try {
|
186
|
-
Filter("uri =~ %r{hello/");
|
186
|
+
(void) Filter("uri =~ %r{hello/");
|
187
187
|
fail("Syntax error expected");
|
188
188
|
} catch (const SyntaxError &) {
|
189
189
|
// Pass.
|
data/test/cxx/IOUtilsTest.cpp
CHANGED
@@ -475,9 +475,16 @@ namespace tut {
|
|
475
475
|
Pipe p = createPipe();
|
476
476
|
unsigned long long startTime = SystemTime::getUsec();
|
477
477
|
unsigned long long timeout = 30000;
|
478
|
+
char data1[1024], data2[1024];
|
479
|
+
StaticString data[] = {
|
480
|
+
StaticString(data1, sizeof(data1) - 1),
|
481
|
+
StaticString(data2, sizeof(data2) - 1)
|
482
|
+
};
|
483
|
+
memset(data1, 'x', sizeof(data1));
|
484
|
+
memset(data2, 'y', sizeof(data2));
|
485
|
+
|
478
486
|
try {
|
479
|
-
|
480
|
-
for (int i = 0; i < 1024 * 1024; i++) {
|
487
|
+
for (int i = 0; i < 1024; i++) {
|
481
488
|
gatheredWrite(p[1], data, 2, &timeout);
|
482
489
|
}
|
483
490
|
fail("TimeoutException expected");
|
@@ -804,7 +811,7 @@ namespace tut {
|
|
804
811
|
SocketPair sockets = createUnixSocketPair();
|
805
812
|
Pipe pipes = createPipe();
|
806
813
|
writeFileDescriptor(sockets[0], pipes[1]);
|
807
|
-
FileDescriptor fd
|
814
|
+
FileDescriptor fd(readFileDescriptor(sockets[1]));
|
808
815
|
writeExact(fd, "hello");
|
809
816
|
char buf[6];
|
810
817
|
ensure_equals(readExact(pipes[0], buf, 5), 5u);
|
@@ -820,7 +827,7 @@ namespace tut {
|
|
820
827
|
unsigned long long timeout = 30000;
|
821
828
|
unsigned long long startTime = SystemTime::getUsec();
|
822
829
|
try {
|
823
|
-
FileDescriptor fd
|
830
|
+
FileDescriptor fd(readFileDescriptor(sockets[0], &timeout));
|
824
831
|
fail("TimeoutException expected");
|
825
832
|
} catch (const TimeoutException &) {
|
826
833
|
unsigned long long elapsed = SystemTime::getUsec() - startTime;
|
@@ -4,7 +4,7 @@
|
|
4
4
|
#include <boost/bind.hpp>
|
5
5
|
|
6
6
|
#include "MessageServer.h"
|
7
|
-
#include "
|
7
|
+
#include "MessageClient.h"
|
8
8
|
#include "Utils.h"
|
9
9
|
#include <string>
|
10
10
|
#include <cstring>
|
@@ -12,7 +12,6 @@
|
|
12
12
|
#include <errno.h>
|
13
13
|
|
14
14
|
using namespace Passenger;
|
15
|
-
using namespace Passenger::ApplicationPool;
|
16
15
|
using namespace boost;
|
17
16
|
using namespace std;
|
18
17
|
|
@@ -21,6 +20,7 @@ namespace tut {
|
|
21
20
|
ServerInstanceDirPtr serverInstanceDir;
|
22
21
|
ServerInstanceDir::GenerationPtr generation;
|
23
22
|
string socketFilename;
|
23
|
+
string socketAddress;
|
24
24
|
AccountsDatabasePtr accountsDatabase;
|
25
25
|
AccountPtr clientAccount;
|
26
26
|
shared_ptr<MessageServer> server;
|
@@ -29,6 +29,7 @@ namespace tut {
|
|
29
29
|
MessageServerTest() {
|
30
30
|
createServerInstanceDirAndGeneration(serverInstanceDir, generation);
|
31
31
|
socketFilename = generation->getPath() + "/socket";
|
32
|
+
socketAddress = "unix:" + socketFilename;
|
32
33
|
accountsDatabase = ptr(new AccountsDatabase());
|
33
34
|
clientAccount = accountsDatabase->add("test", "12345", false);
|
34
35
|
|
@@ -45,40 +46,40 @@ namespace tut {
|
|
45
46
|
Passenger::setLogLevel(0);
|
46
47
|
}
|
47
48
|
|
48
|
-
class SlowClient: public
|
49
|
+
class SlowClient: public MessageClient {
|
49
50
|
private:
|
50
51
|
unsigned int timeToSendUsername;
|
51
52
|
unsigned int timeToSendPassword;
|
52
53
|
|
53
54
|
protected:
|
54
|
-
virtual void sendUsername(
|
55
|
+
virtual void sendUsername(int fd, const StaticString &username, unsigned long long *timeout) {
|
55
56
|
if (timeToSendUsername > 0) {
|
56
57
|
usleep(timeToSendUsername * 1000);
|
57
58
|
}
|
58
|
-
|
59
|
+
writeScalarMessage(fd, username);
|
59
60
|
}
|
60
61
|
|
61
|
-
virtual void sendPassword(
|
62
|
+
virtual void sendPassword(int fd, const StaticString &userSuppliedPassword, unsigned long long *timeout) {
|
62
63
|
if (timeToSendPassword > 0) {
|
63
64
|
usleep(timeToSendPassword * 1000);
|
64
65
|
}
|
65
|
-
|
66
|
+
writeScalarMessage(fd, userSuppliedPassword);
|
66
67
|
}
|
67
68
|
|
68
69
|
public:
|
69
70
|
SlowClient(unsigned int timeToSendUsername,
|
70
71
|
unsigned int timeToSendPassword)
|
71
|
-
:
|
72
|
+
: MessageClient()
|
72
73
|
{
|
73
74
|
this->timeToSendUsername = timeToSendUsername;
|
74
75
|
this->timeToSendPassword = timeToSendPassword;
|
75
76
|
}
|
76
77
|
};
|
77
78
|
|
78
|
-
class CustomClient: public
|
79
|
+
class CustomClient: public MessageClient {
|
79
80
|
public:
|
80
81
|
CustomClient *sendText(const string &text) {
|
81
|
-
|
82
|
+
write(text.c_str(), NULL);
|
82
83
|
return this;
|
83
84
|
}
|
84
85
|
};
|
@@ -153,19 +154,19 @@ namespace tut {
|
|
153
154
|
accountsDatabase->add("hashed_user", Account::createHash("67890"), true);
|
154
155
|
|
155
156
|
try {
|
156
|
-
|
157
|
+
MessageClient().connect(socketAddress, "testt", "12345");
|
157
158
|
fail("SecurityException expected when invalid username is given");
|
158
159
|
} catch (const SecurityException &) {
|
159
160
|
// Pass.
|
160
161
|
}
|
161
162
|
try {
|
162
|
-
|
163
|
+
MessageClient().connect(socketAddress, "test", "123456");
|
163
164
|
fail("SecurityException expected when invalid password is given for an account with plain text password");
|
164
165
|
} catch (const SecurityException &) {
|
165
166
|
// Pass.
|
166
167
|
}
|
167
168
|
try {
|
168
|
-
|
169
|
+
MessageClient().connect(socketAddress, "test", "678900");
|
169
170
|
fail("SecurityException expected when invalid password is given for an account with hashed password");
|
170
171
|
} catch (const SecurityException &) {
|
171
172
|
// Pass.
|
@@ -175,14 +176,14 @@ namespace tut {
|
|
175
176
|
TEST_METHOD(2) {
|
176
177
|
// It supports hashed passwords.
|
177
178
|
accountsDatabase->add("hashed_user", Account::createHash("67890"), true);
|
178
|
-
|
179
|
+
MessageClient().connect(socketAddress, "hashed_user", "67890"); // Should not throw exception.
|
179
180
|
}
|
180
181
|
|
181
182
|
TEST_METHOD(3) {
|
182
183
|
// It disconnects the client if the client does not supply a username and
|
183
184
|
// password within a time limit.
|
184
185
|
Passenger::setLogLevel(-1);
|
185
|
-
server->setLoginTimeout(
|
186
|
+
server->setLoginTimeout(30000);
|
186
187
|
|
187
188
|
/* These can throw either an IOException or SystemException:
|
188
189
|
* - An IOException is raised when connect() encounters EOF.
|
@@ -193,7 +194,7 @@ namespace tut {
|
|
193
194
|
|
194
195
|
try {
|
195
196
|
// This client takes too much time on sending the username.
|
196
|
-
SlowClient(50, 0).connect(
|
197
|
+
SlowClient(50, 0).connect(socketAddress, "test", "12345");
|
197
198
|
fail("IOException or SystemException expected (1).");
|
198
199
|
} catch (const IOException &e) {
|
199
200
|
// Pass.
|
@@ -203,7 +204,7 @@ namespace tut {
|
|
203
204
|
|
204
205
|
try {
|
205
206
|
// This client takes too much time on sending the password.
|
206
|
-
SlowClient(0, 50).connect(
|
207
|
+
SlowClient(0, 50).connect(socketAddress, "test", "12345");
|
207
208
|
fail("IOException or SystemException expected (2).");
|
208
209
|
} catch (const IOException &e) {
|
209
210
|
// Pass.
|
@@ -214,7 +215,7 @@ namespace tut {
|
|
214
215
|
try {
|
215
216
|
// This client is fast enough at sending the username and
|
216
217
|
// password individually, but the combined time is too long.
|
217
|
-
SlowClient(25, 25).connect(
|
218
|
+
SlowClient(25, 25).connect(socketAddress, "test", "12345");
|
218
219
|
fail("IOException or SystemException expected (3).");
|
219
220
|
} catch (const IOException &e) {
|
220
221
|
// Pass.
|
@@ -229,7 +230,7 @@ namespace tut {
|
|
229
230
|
memset(username, 'x', sizeof(username));
|
230
231
|
username[sizeof(username) - 1] = '\0';
|
231
232
|
try {
|
232
|
-
|
233
|
+
MessageClient().connect(socketAddress, username, "1234");
|
233
234
|
fail("SecurityException expected");
|
234
235
|
} catch (const SecurityException &e) {
|
235
236
|
// Pass.
|
@@ -242,7 +243,7 @@ namespace tut {
|
|
242
243
|
memset(password, 'x', sizeof(password));
|
243
244
|
password[sizeof(password) - 1] = '\0';
|
244
245
|
try {
|
245
|
-
|
246
|
+
MessageClient().connect(socketAddress, "test", password);
|
246
247
|
fail("SecurityException expected");
|
247
248
|
} catch (const SecurityException &e) {
|
248
249
|
// Pass.
|
@@ -255,8 +256,8 @@ namespace tut {
|
|
255
256
|
LoggingHandlerPtr handler2(new LoggingHandler());
|
256
257
|
server->addHandler(handler1);
|
257
258
|
server->addHandler(handler2);
|
258
|
-
|
259
|
-
|
259
|
+
MessageClient().connect(socketAddress, "test", "12345");
|
260
|
+
MessageClient().connect(socketAddress, "test", "12345");
|
260
261
|
|
261
262
|
usleep(10000); // Give the threads some time to do work.
|
262
263
|
ensure_equals(handler1->clientsAccepted, 2);
|
@@ -275,12 +276,12 @@ namespace tut {
|
|
275
276
|
handler1->returnValue = false;
|
276
277
|
|
277
278
|
CustomClient c1, c2;
|
278
|
-
c1.connect(
|
279
|
+
c1.connect(socketAddress, "test", "12345");
|
279
280
|
c1.sendText("hello");
|
280
281
|
c1.sendText(" ");
|
281
282
|
usleep(10000); // Give the thread some time to do work.
|
282
283
|
|
283
|
-
c2.connect(
|
284
|
+
c2.connect(socketAddress, "test", "12345");
|
284
285
|
c2.sendText("world");
|
285
286
|
usleep(10000); // Give the thread some time to do work.
|
286
287
|
|
@@ -298,7 +299,7 @@ namespace tut {
|
|
298
299
|
server->addHandler(handler2);
|
299
300
|
|
300
301
|
CustomClient c;
|
301
|
-
c.connect(
|
302
|
+
c.connect(socketAddress, "test", "12345");
|
302
303
|
c.sendText("hi");
|
303
304
|
usleep(10000); // Give the thread some time to do work.
|
304
305
|
|
@@ -314,7 +315,7 @@ namespace tut {
|
|
314
315
|
server->addHandler(handler2);
|
315
316
|
|
316
317
|
CustomClient c;
|
317
|
-
c.connect(
|
318
|
+
c.connect(socketAddress, "test", "12345");
|
318
319
|
c.sendText("hi");
|
319
320
|
usleep(10000); // Give the thread some time to do work.
|
320
321
|
|
@@ -342,7 +343,7 @@ namespace tut {
|
|
342
343
|
|
343
344
|
handler1->id = 100;
|
344
345
|
handler2->id = 101;
|
345
|
-
c1.connect(
|
346
|
+
c1.connect(socketAddress, "test", "12345");
|
346
347
|
c1.sendText("hi");
|
347
348
|
usleep(10000); // Give the thread some time to do work.
|
348
349
|
ensure_equals(handler1->latestContext->id, 100);
|
@@ -350,7 +351,7 @@ namespace tut {
|
|
350
351
|
|
351
352
|
handler1->id = 200;
|
352
353
|
handler2->id = 201;
|
353
|
-
c2.connect(
|
354
|
+
c2.connect(socketAddress, "test", "12345");
|
354
355
|
c2.sendText("hi");
|
355
356
|
usleep(10000); // Give the thread some time to do work.
|
356
357
|
ensure_equals(handler1->latestContext->id, 200);
|
@@ -370,13 +371,13 @@ namespace tut {
|
|
370
371
|
server->addHandler(handler2);
|
371
372
|
{
|
372
373
|
{
|
373
|
-
|
374
|
+
MessageClient().connect(socketAddress, "test", "12345");
|
374
375
|
}
|
375
376
|
usleep(10000); // Give the threads some time to do work.
|
376
377
|
ensure_equals(handler1->clientsDisconnected, 1);
|
377
378
|
ensure_equals(handler2->clientsDisconnected, 1);
|
378
379
|
|
379
|
-
|
380
|
+
MessageClient().connect(socketAddress, "test", "12345");
|
380
381
|
}
|
381
382
|
usleep(10000); // Give the threads some time to do work.
|
382
383
|
ensure_equals(handler1->clientsDisconnected, 2);
|
@@ -0,0 +1,777 @@
|
|
1
|
+
#include <TestSupport.h>
|
2
|
+
#include <agents/HelperAgent/RequestHandler.h>
|
3
|
+
#include <agents/HelperAgent/RequestHandler.cpp>
|
4
|
+
#include <agents/HelperAgent/AgentOptions.h>
|
5
|
+
#include <ApplicationPool2/Pool.h>
|
6
|
+
#include <Utils/IOUtils.h>
|
7
|
+
#include <Utils/Timer.h>
|
8
|
+
|
9
|
+
#include <boost/shared_array.hpp>
|
10
|
+
#include <string>
|
11
|
+
#include <vector>
|
12
|
+
#include <map>
|
13
|
+
#include <sstream>
|
14
|
+
#include <cstdarg>
|
15
|
+
#include <sys/socket.h>
|
16
|
+
|
17
|
+
using namespace std;
|
18
|
+
using namespace boost;
|
19
|
+
using namespace Passenger;
|
20
|
+
using namespace Passenger::ApplicationPool2;
|
21
|
+
|
22
|
+
namespace tut {
|
23
|
+
struct RequestHandlerTest {
|
24
|
+
ServerInstanceDirPtr serverInstanceDir;
|
25
|
+
ServerInstanceDir::GenerationPtr generation;
|
26
|
+
string serverFilename;
|
27
|
+
FileDescriptor requestSocket;
|
28
|
+
AgentOptions agentOptions;
|
29
|
+
|
30
|
+
BackgroundEventLoop bg;
|
31
|
+
SpawnerFactoryPtr spawnerFactory;
|
32
|
+
PoolPtr pool;
|
33
|
+
shared_ptr<RequestHandler> handler;
|
34
|
+
FileDescriptor connection;
|
35
|
+
map<string, string> defaultHeaders;
|
36
|
+
|
37
|
+
string root;
|
38
|
+
string rackAppPath, wsgiAppPath;
|
39
|
+
|
40
|
+
RequestHandlerTest() {
|
41
|
+
createServerInstanceDirAndGeneration(serverInstanceDir, generation);
|
42
|
+
spawnerFactory = make_shared<SpawnerFactory>(bg.safe, *resourceLocator, generation);
|
43
|
+
pool = make_shared<Pool>(bg.safe.get(), spawnerFactory);
|
44
|
+
serverFilename = generation->getPath() + "/server";
|
45
|
+
requestSocket = createUnixServer(serverFilename);
|
46
|
+
setNonBlocking(requestSocket);
|
47
|
+
|
48
|
+
agentOptions.passengerRoot = resourceLocator->getRoot();
|
49
|
+
root = resourceLocator->getRoot();
|
50
|
+
rackAppPath = root + "/test/stub/rack";
|
51
|
+
wsgiAppPath = root + "/test/stub/wsgi";
|
52
|
+
defaultHeaders["PASSENGER_LOAD_SHELL_ENVVARS"] = "false";
|
53
|
+
defaultHeaders["PASSENGER_APP_TYPE"] = "wsgi";
|
54
|
+
defaultHeaders["PASSENGER_SPAWN_METHOD"] = "direct";
|
55
|
+
defaultHeaders["REQUEST_METHOD"] = "GET";
|
56
|
+
}
|
57
|
+
|
58
|
+
~RequestHandlerTest() {
|
59
|
+
setLogLevel(0);
|
60
|
+
unlink(serverFilename.c_str());
|
61
|
+
handler.reset();
|
62
|
+
pool->destroy();
|
63
|
+
pool.reset();
|
64
|
+
}
|
65
|
+
|
66
|
+
void init() {
|
67
|
+
handler = make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
|
68
|
+
bg.start();
|
69
|
+
}
|
70
|
+
|
71
|
+
FileDescriptor &connect() {
|
72
|
+
connection = connectToUnixServer(serverFilename);
|
73
|
+
return connection;
|
74
|
+
}
|
75
|
+
|
76
|
+
void sendHeaders(const map<string, string> &headers, ...) {
|
77
|
+
va_list ap;
|
78
|
+
const char *arg;
|
79
|
+
map<string, string>::const_iterator it;
|
80
|
+
vector<StaticString> args;
|
81
|
+
|
82
|
+
for (it = headers.begin(); it != headers.end(); it++) {
|
83
|
+
args.push_back(StaticString(it->first.data(), it->first.size() + 1));
|
84
|
+
args.push_back(StaticString(it->second.data(), it->second.size() + 1));
|
85
|
+
}
|
86
|
+
|
87
|
+
va_start(ap, headers);
|
88
|
+
while ((arg = va_arg(ap, const char *)) != NULL) {
|
89
|
+
args.push_back(StaticString(arg, strlen(arg) + 1));
|
90
|
+
}
|
91
|
+
va_end(ap);
|
92
|
+
|
93
|
+
shared_array<StaticString> args_array(new StaticString[args.size() + 2]);
|
94
|
+
unsigned int totalSize = 0;
|
95
|
+
for (unsigned int i = 0; i < args.size(); i++) {
|
96
|
+
args_array[i + 1] = args[i];
|
97
|
+
totalSize += args[i].size();
|
98
|
+
}
|
99
|
+
char totalSizeString[10];
|
100
|
+
snprintf(totalSizeString, sizeof(totalSizeString), "%u:", totalSize);
|
101
|
+
args_array[0] = StaticString(totalSizeString);
|
102
|
+
args_array[args.size() + 1] = ",";
|
103
|
+
|
104
|
+
gatheredWrite(connection, args_array.get(), args.size() + 2, NULL);
|
105
|
+
}
|
106
|
+
|
107
|
+
string stripHeaders(const string &str) {
|
108
|
+
string::size_type pos = str.find("\r\n\r\n");
|
109
|
+
if (pos == string::npos) {
|
110
|
+
return str;
|
111
|
+
} else {
|
112
|
+
string result = str;
|
113
|
+
result.erase(0, pos + 4);
|
114
|
+
return result;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
string inspect() {
|
119
|
+
string result;
|
120
|
+
bg.safe->runSync(boost::bind(&RequestHandlerTest::real_inspect, this, &result));
|
121
|
+
return result;
|
122
|
+
}
|
123
|
+
|
124
|
+
void real_inspect(string *result) {
|
125
|
+
stringstream stream;
|
126
|
+
handler->inspect(stream);
|
127
|
+
*result = stream.str();
|
128
|
+
}
|
129
|
+
|
130
|
+
static void writeBody(FileDescriptor conn, string body) {
|
131
|
+
try {
|
132
|
+
writeExact(conn, body);
|
133
|
+
} catch (const SystemException &e) {
|
134
|
+
if (e.code() == EPIPE) {
|
135
|
+
// Ignore.
|
136
|
+
} else {
|
137
|
+
throw;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
}
|
141
|
+
};
|
142
|
+
|
143
|
+
DEFINE_TEST_GROUP(RequestHandlerTest);
|
144
|
+
|
145
|
+
TEST_METHOD(1) {
|
146
|
+
// Test one normal request.
|
147
|
+
init();
|
148
|
+
connect();
|
149
|
+
sendHeaders(defaultHeaders,
|
150
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
151
|
+
"PATH_INFO", "/",
|
152
|
+
NULL);
|
153
|
+
string response = readAll(connection);
|
154
|
+
string body = stripHeaders(response);
|
155
|
+
ensure("Status line is correct", containsSubstring(response, "HTTP/1.1 200 OK\r\n"));
|
156
|
+
ensure("Headers are correct", containsSubstring(response, "Content-Type: text/html\r\n"));
|
157
|
+
ensure("Contains a Status header", containsSubstring(response, "Status: 200 OK\r\n"));
|
158
|
+
ensure_equals(body, "hello <b>world</b>");
|
159
|
+
}
|
160
|
+
|
161
|
+
TEST_METHOD(2) {
|
162
|
+
// Test multiple normal requests.
|
163
|
+
init();
|
164
|
+
for (int i = 0; i < 10; i++) {
|
165
|
+
connect();
|
166
|
+
sendHeaders(defaultHeaders,
|
167
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
168
|
+
"PATH_INFO", "/",
|
169
|
+
NULL);
|
170
|
+
string response = readAll(connection);
|
171
|
+
string body = stripHeaders(response);
|
172
|
+
ensure("Status line is correct", containsSubstring(response, "HTTP/1.1 200 OK\r\n"));
|
173
|
+
ensure("Headers are correct", containsSubstring(response, "Content-Type: text/html\r\n"));
|
174
|
+
ensure("Contains a Status header", containsSubstring(response, "Status: 200 OK\r\n"));
|
175
|
+
ensure_equals(body, "hello <b>world</b>");
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
TEST_METHOD(3) {
|
180
|
+
// Test sending request data in pieces.
|
181
|
+
defaultHeaders["PASSENGER_APP_ROOT"] = wsgiAppPath;
|
182
|
+
defaultHeaders["PATH_INFO"] = "/";
|
183
|
+
|
184
|
+
string request;
|
185
|
+
map<string, string>::const_iterator it, end = defaultHeaders.end();
|
186
|
+
for (it = defaultHeaders.begin(); it != end; it++) {
|
187
|
+
request.append(it->first);
|
188
|
+
request.append(1, '\0');
|
189
|
+
request.append(it->second);
|
190
|
+
request.append(1, '\0');
|
191
|
+
}
|
192
|
+
request = toString(request.size()) + ":" + request;
|
193
|
+
request.append(",");
|
194
|
+
|
195
|
+
init();
|
196
|
+
connect();
|
197
|
+
string::size_type i = 0;
|
198
|
+
while (i < request.size()) {
|
199
|
+
const string piece = const_cast<const string &>(request).substr(i, 5);
|
200
|
+
writeExact(connection, piece);
|
201
|
+
usleep(10000);
|
202
|
+
i += piece.size();
|
203
|
+
}
|
204
|
+
|
205
|
+
string response = readAll(connection);
|
206
|
+
string body = stripHeaders(response);
|
207
|
+
ensure("Status line is correct", containsSubstring(response, "HTTP/1.1 200 OK\r\n"));
|
208
|
+
ensure("Headers are correct", containsSubstring(response, "Content-Type: text/html\r\n"));
|
209
|
+
ensure("Contains a Status header", containsSubstring(response, "Status: 200 OK\r\n"));
|
210
|
+
ensure_equals(body, "hello <b>world</b>");
|
211
|
+
}
|
212
|
+
|
213
|
+
TEST_METHOD(4) {
|
214
|
+
// It denies access if the connect password is wrong.
|
215
|
+
agentOptions.requestSocketPassword = "hello world";
|
216
|
+
setLogLevel(-1);
|
217
|
+
init();
|
218
|
+
|
219
|
+
connect();
|
220
|
+
writeExact(connection, "hello world");
|
221
|
+
sendHeaders(defaultHeaders,
|
222
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
223
|
+
"PATH_INFO", "/",
|
224
|
+
NULL
|
225
|
+
);
|
226
|
+
ensure(containsSubstring(readAll(connection), "hello <b>world</b>"));
|
227
|
+
|
228
|
+
connect();
|
229
|
+
try {
|
230
|
+
sendHeaders(defaultHeaders,
|
231
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
232
|
+
"PATH_INFO", "/",
|
233
|
+
NULL
|
234
|
+
);
|
235
|
+
} catch (const SystemException &e) {
|
236
|
+
ensure_equals(e.code(), EPIPE);
|
237
|
+
return;
|
238
|
+
}
|
239
|
+
string response;
|
240
|
+
try {
|
241
|
+
response = readAll(connection);
|
242
|
+
} catch (const SystemException &e) {
|
243
|
+
ensure_equals(e.code(), ECONNRESET);
|
244
|
+
return;
|
245
|
+
}
|
246
|
+
ensure_equals(response, "");
|
247
|
+
}
|
248
|
+
|
249
|
+
TEST_METHOD(5) {
|
250
|
+
// It disconnects us if the connect password is not sent within a certain time.
|
251
|
+
agentOptions.requestSocketPassword = "hello world";
|
252
|
+
setLogLevel(-1);
|
253
|
+
handler = make_shared<RequestHandler>(bg.safe, requestSocket, pool, agentOptions);
|
254
|
+
handler->connectPasswordTimeout = 40;
|
255
|
+
bg.start();
|
256
|
+
|
257
|
+
connect();
|
258
|
+
Timer timer;
|
259
|
+
readAll(connection);
|
260
|
+
timer.stop();
|
261
|
+
ensure(timer.elapsed() <= 60);
|
262
|
+
}
|
263
|
+
|
264
|
+
TEST_METHOD(6) {
|
265
|
+
// It works correct if the connect password is sent in pieces.
|
266
|
+
agentOptions.requestSocketPassword = "hello world";
|
267
|
+
init();
|
268
|
+
connect();
|
269
|
+
writeExact(connection, "hello");
|
270
|
+
usleep(10000);
|
271
|
+
writeExact(connection, " world");
|
272
|
+
usleep(10000);
|
273
|
+
sendHeaders(defaultHeaders,
|
274
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
275
|
+
"PATH_INFO", "/",
|
276
|
+
NULL
|
277
|
+
);
|
278
|
+
ensure(containsSubstring(readAll(connection), "hello <b>world</b>"));
|
279
|
+
}
|
280
|
+
|
281
|
+
TEST_METHOD(7) {
|
282
|
+
// It closes the connection with the application if the client has closed the connection.
|
283
|
+
init();
|
284
|
+
connect();
|
285
|
+
sendHeaders(defaultHeaders,
|
286
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
287
|
+
"PATH_INFO", "/stream",
|
288
|
+
NULL
|
289
|
+
);
|
290
|
+
BufferedIO io(connection);
|
291
|
+
ensure_equals(io.readLine(), "HTTP/1.1 200 OK\r\n");
|
292
|
+
ensure_equals(pool->getProcessCount(), 1u);
|
293
|
+
SuperGroupPtr superGroup = pool->superGroups.get(wsgiAppPath);
|
294
|
+
ProcessPtr process = superGroup->defaultGroup->processes.front();
|
295
|
+
ensure_equals(process->sessions, 1);
|
296
|
+
connection.close();
|
297
|
+
EVENTUALLY(5,
|
298
|
+
result = process->sessions == 0;
|
299
|
+
);
|
300
|
+
}
|
301
|
+
|
302
|
+
TEST_METHOD(10) {
|
303
|
+
// If the app crashes at startup without an error page then it renders
|
304
|
+
// a generic error page.
|
305
|
+
TempDir tempdir("tmp.handler");
|
306
|
+
writeFile("tmp.handler/start.rb",
|
307
|
+
"STDERR.puts 'I have failed'");
|
308
|
+
|
309
|
+
setLogLevel(-2);
|
310
|
+
spawnerFactory->forwardStderr = false;
|
311
|
+
init();
|
312
|
+
connect();
|
313
|
+
sendHeaders(defaultHeaders,
|
314
|
+
"PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
|
315
|
+
"PASSENGER_APP_TYPE", "",
|
316
|
+
"PASSENGER_START_COMMAND", ("ruby\1" + root + "/test/tmp.handler/start.rb").c_str(),
|
317
|
+
"PATH_INFO", "/",
|
318
|
+
NULL);
|
319
|
+
string response = readAll(connection);
|
320
|
+
ensure(containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
|
321
|
+
ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
|
322
|
+
ensure(containsSubstring(response, "I have failed"));
|
323
|
+
}
|
324
|
+
|
325
|
+
TEST_METHOD(11) {
|
326
|
+
// If the app crashes at startup with an error page then it renders
|
327
|
+
// a friendly error page.
|
328
|
+
TempDir tempdir("tmp.handler");
|
329
|
+
writeFile("tmp.handler/start.rb",
|
330
|
+
"STDERR.puts 'Error'\n"
|
331
|
+
"STDERR.puts\n"
|
332
|
+
"STDERR.puts 'I have failed'\n");
|
333
|
+
|
334
|
+
setLogLevel(-2);
|
335
|
+
spawnerFactory->forwardStderr = false;
|
336
|
+
init();
|
337
|
+
connect();
|
338
|
+
sendHeaders(defaultHeaders,
|
339
|
+
"PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
|
340
|
+
"PASSENGER_APP_TYPE", "",
|
341
|
+
"PASSENGER_START_COMMAND", ("ruby\1" + root + "/test/tmp.handler/start.rb").c_str(),
|
342
|
+
"PATH_INFO", "/",
|
343
|
+
NULL);
|
344
|
+
string response = readAll(connection);
|
345
|
+
ensure(containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
|
346
|
+
ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
|
347
|
+
ensure(containsSubstring(response, "Content-Type: text/html; charset=UTF-8\r\n"));
|
348
|
+
ensure(containsSubstring(response, "<html>"));
|
349
|
+
ensure(containsSubstring(response, "I have failed"));
|
350
|
+
}
|
351
|
+
|
352
|
+
TEST_METHOD(12) {
|
353
|
+
// If spawning fails because of an internal error then it reports the error appropriately.
|
354
|
+
TempDir tempdir("tmp.handler");
|
355
|
+
writeFile("tmp.handler/start.rb", "");
|
356
|
+
|
357
|
+
setLogLevel(-2);
|
358
|
+
spawnerFactory->forwardStderr = false;
|
359
|
+
init();
|
360
|
+
connect();
|
361
|
+
sendHeaders(defaultHeaders,
|
362
|
+
"PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
|
363
|
+
"PASSENGER_APP_TYPE", "",
|
364
|
+
"PASSENGER_START_COMMAND", ("ruby\1" + root + "/test/tmp.handler/start.rb").c_str(),
|
365
|
+
"PASSENGER_RAISE_INTERNAL_ERROR", "true",
|
366
|
+
"PATH_INFO", "/",
|
367
|
+
NULL);
|
368
|
+
string response = readAll(connection);
|
369
|
+
ensure(containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
|
370
|
+
ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
|
371
|
+
ensure(containsSubstring(response, "Content-Type: text/html; charset=UTF-8\r\n"));
|
372
|
+
ensure(containsSubstring(response, "<html>"));
|
373
|
+
ensure(containsSubstring(response, "An internal error occurred while trying to spawn the application."));
|
374
|
+
ensure(containsSubstring(response, "Passenger:<wbr>:<wbr>RuntimeException"));
|
375
|
+
ensure(containsSubstring(response, "An internal error!"));
|
376
|
+
ensure(containsSubstring(response, "Spawner.h"));
|
377
|
+
}
|
378
|
+
|
379
|
+
TEST_METHOD(13) {
|
380
|
+
// Error pages respect the PASSENGER_STATUS_LINE option.
|
381
|
+
TempDir tempdir("tmp.handler");
|
382
|
+
writeFile("tmp.handler/start.rb",
|
383
|
+
"STDERR.puts 'I have failed'");
|
384
|
+
|
385
|
+
setLogLevel(-2);
|
386
|
+
spawnerFactory->forwardStderr = false;
|
387
|
+
init();
|
388
|
+
connect();
|
389
|
+
sendHeaders(defaultHeaders,
|
390
|
+
"PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
|
391
|
+
"PASSENGER_APP_TYPE", "",
|
392
|
+
"PASSENGER_START_COMMAND", ("ruby\1" + root + "/test/tmp.handler/start.rb").c_str(),
|
393
|
+
"PASSENGER_STATUS_LINE", "false",
|
394
|
+
"PATH_INFO", "/",
|
395
|
+
NULL);
|
396
|
+
string response = readAll(connection);
|
397
|
+
ensure(!containsSubstring(response, "HTTP/1.1 "));
|
398
|
+
ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
|
399
|
+
ensure(containsSubstring(response, "I have failed"));
|
400
|
+
}
|
401
|
+
|
402
|
+
TEST_METHOD(14) {
|
403
|
+
// If PASSENGER_FRIENDLY_ERROR_PAGES is false then it does not render
|
404
|
+
// a friendly error page.
|
405
|
+
TempDir tempdir("tmp.handler");
|
406
|
+
writeFile("tmp.handler/start.rb",
|
407
|
+
"STDERR.puts 'Error'\n"
|
408
|
+
"STDERR.puts\n"
|
409
|
+
"STDERR.puts 'I have failed'\n");
|
410
|
+
|
411
|
+
setLogLevel(-2);
|
412
|
+
spawnerFactory->forwardStderr = false;
|
413
|
+
init();
|
414
|
+
connect();
|
415
|
+
sendHeaders(defaultHeaders,
|
416
|
+
"PASSENGER_APP_ROOT", (root + "/test/tmp.handler").c_str(),
|
417
|
+
"PASSENGER_APP_TYPE", "",
|
418
|
+
"PASSENGER_START_COMMAND", ("ruby\1" + root + "/test/tmp.handler/start.rb").c_str(),
|
419
|
+
"PASSENGER_FRIENDLY_ERROR_PAGES", "false",
|
420
|
+
"PATH_INFO", "/",
|
421
|
+
NULL);
|
422
|
+
string response = readAll(connection);
|
423
|
+
ensure(containsSubstring(response, "HTTP/1.1 500 Internal Server Error\r\n"));
|
424
|
+
ensure(containsSubstring(response, "Status: 500 Internal Server Error\r\n"));
|
425
|
+
ensure(containsSubstring(response, "Content-Type: text/html; charset=UTF-8\r\n"));
|
426
|
+
ensure(containsSubstring(response, "<html>"));
|
427
|
+
ensure(!containsSubstring(response, "I have failed"));
|
428
|
+
ensure(containsSubstring(response, "We're sorry, but something went wrong"));
|
429
|
+
}
|
430
|
+
|
431
|
+
TEST_METHOD(20) {
|
432
|
+
// It streams the request body to the application.
|
433
|
+
DeleteFileEventually file("tmp.output");
|
434
|
+
|
435
|
+
init();
|
436
|
+
connect();
|
437
|
+
sendHeaders(defaultHeaders,
|
438
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
439
|
+
"PATH_INFO", "/upload",
|
440
|
+
"HTTP_X_OUTPUT", (root + "/test/tmp.output").c_str(),
|
441
|
+
NULL);
|
442
|
+
writeExact(connection, "hello\n");
|
443
|
+
EVENTUALLY(5,
|
444
|
+
result = fileExists("tmp.output") && readAll("tmp.output") == "hello\n";
|
445
|
+
);
|
446
|
+
writeExact(connection, "world\n");
|
447
|
+
EVENTUALLY(3,
|
448
|
+
result = readAll("tmp.output") == "hello\nworld\n";
|
449
|
+
);
|
450
|
+
shutdown(connection, SHUT_WR);
|
451
|
+
ensure_equals(stripHeaders(readAll(connection)), "ok");
|
452
|
+
}
|
453
|
+
|
454
|
+
TEST_METHOD(21) {
|
455
|
+
// It buffers the request body if PASSENGER_BUFFERING is true.
|
456
|
+
DeleteFileEventually file("tmp.output");
|
457
|
+
|
458
|
+
init();
|
459
|
+
connect();
|
460
|
+
sendHeaders(defaultHeaders,
|
461
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
462
|
+
"PASSENGER_BUFFERING", "true",
|
463
|
+
"PATH_INFO", "/upload",
|
464
|
+
"HTTP_X_OUTPUT", (root + "/test/tmp.output").c_str(),
|
465
|
+
NULL);
|
466
|
+
writeExact(connection, "hello\n");
|
467
|
+
SHOULD_NEVER_HAPPEN(200,
|
468
|
+
result = fileExists("tmp.output");
|
469
|
+
);
|
470
|
+
writeExact(connection, "world\n");
|
471
|
+
SHOULD_NEVER_HAPPEN(200,
|
472
|
+
result = fileExists("tmp.output");
|
473
|
+
);
|
474
|
+
shutdown(connection, SHUT_WR);
|
475
|
+
ensure_equals(stripHeaders(readAll(connection)), "ok");
|
476
|
+
}
|
477
|
+
|
478
|
+
TEST_METHOD(22) {
|
479
|
+
set_test_name("Test buffering of large request bodies that fit in neither the socket "
|
480
|
+
"buffer nor the FileBackedPipe memory buffer, and that the application "
|
481
|
+
"cannot read quickly enough.");
|
482
|
+
|
483
|
+
DeleteFileEventually d1("/tmp/wait.txt");
|
484
|
+
DeleteFileEventually d2("/tmp/output.txt");
|
485
|
+
|
486
|
+
// 2.6 MB of request body. Guaranteed not to fit in any socket buffer.
|
487
|
+
string requestBody;
|
488
|
+
for (int i = 0; i < 204800; i++) {
|
489
|
+
requestBody.append("hello world!\n");
|
490
|
+
}
|
491
|
+
|
492
|
+
init();
|
493
|
+
connect();
|
494
|
+
sendHeaders(defaultHeaders,
|
495
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
496
|
+
"PATH_INFO", "/upload",
|
497
|
+
"PASSENGER_BUFFERING", "true",
|
498
|
+
"HTTP_X_WAIT_FOR_FILE", "/tmp/wait.txt",
|
499
|
+
"HTTP_X_OUTPUT", "/tmp/output.txt",
|
500
|
+
NULL);
|
501
|
+
|
502
|
+
// Should not block.
|
503
|
+
writeExact(connection, requestBody);
|
504
|
+
shutdown(connection, SHUT_WR);
|
505
|
+
|
506
|
+
EVENTUALLY(5,
|
507
|
+
result = containsSubstring(inspect(), "session initiated = true");
|
508
|
+
);
|
509
|
+
touchFile("/tmp/wait.txt");
|
510
|
+
|
511
|
+
string result = stripHeaders(readAll(connection));
|
512
|
+
ensure_equals(result, "ok");
|
513
|
+
struct stat buf;
|
514
|
+
ensure(stat("/tmp/output.txt", &buf) == 0);
|
515
|
+
ensure_equals(buf.st_size, (off_t) requestBody.size());
|
516
|
+
}
|
517
|
+
|
518
|
+
TEST_METHOD(30) {
|
519
|
+
// It replaces HTTP_CONTENT_LENGTH with CONTENT_LENGTH.
|
520
|
+
init();
|
521
|
+
connect();
|
522
|
+
sendHeaders(defaultHeaders,
|
523
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
524
|
+
"PATH_INFO", "/env",
|
525
|
+
"HTTP_CONTENT_LENGTH", "5",
|
526
|
+
NULL);
|
527
|
+
writeExact(connection, "hello");
|
528
|
+
string response = readAll(connection);
|
529
|
+
ensure(containsSubstring(response, "CONTENT_LENGTH = 5\n"));
|
530
|
+
ensure(!containsSubstring(response, "HTTP_CONTENT_LENGTH"));
|
531
|
+
}
|
532
|
+
|
533
|
+
TEST_METHOD(31) {
|
534
|
+
// It replaces HTTP_CONTENT_TYPE with CONTENT_TYPE.
|
535
|
+
init();
|
536
|
+
connect();
|
537
|
+
sendHeaders(defaultHeaders,
|
538
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
539
|
+
"PATH_INFO", "/env",
|
540
|
+
"HTTP_CONTENT_TYPE", "application/json",
|
541
|
+
NULL);
|
542
|
+
string response = readAll(connection);
|
543
|
+
ensure(containsSubstring(response, "CONTENT_TYPE = application/json\n"));
|
544
|
+
ensure(!containsSubstring(response, "HTTP_CONTENT_TYPE"));
|
545
|
+
}
|
546
|
+
|
547
|
+
TEST_METHOD(35) {
|
548
|
+
// The response doesn't contain an HTTP status line if PASSENGER_STATUS_LINE is false.
|
549
|
+
init();
|
550
|
+
connect();
|
551
|
+
sendHeaders(defaultHeaders,
|
552
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
553
|
+
"PASSENGER_STATUS_LINE", "false",
|
554
|
+
"PATH_INFO", "/",
|
555
|
+
NULL);
|
556
|
+
string response = readAll(connection);
|
557
|
+
ensure(!containsSubstring(response, "HTTP/1.1 "));
|
558
|
+
ensure(containsSubstring(response, "Status: 200 OK\r\n"));
|
559
|
+
}
|
560
|
+
|
561
|
+
TEST_METHOD(36) {
|
562
|
+
// If the application outputs a status line without a reason phrase,
|
563
|
+
// then a reason phrase is automatically appended.
|
564
|
+
init();
|
565
|
+
connect();
|
566
|
+
sendHeaders(defaultHeaders,
|
567
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
568
|
+
"PATH_INFO", "/custom_status",
|
569
|
+
"HTTP_X_CUSTOM_STATUS", "201",
|
570
|
+
NULL);
|
571
|
+
string response = readAll(connection);
|
572
|
+
ensure(containsSubstring(response, "HTTP/1.1 201 Created\r\n"));
|
573
|
+
ensure(containsSubstring(response, "Status: 201 Created\r\n"));
|
574
|
+
}
|
575
|
+
|
576
|
+
TEST_METHOD(37) {
|
577
|
+
// If the application outputs a status line with a custom reason phrase,
|
578
|
+
// then that reason phrase is used.
|
579
|
+
init();
|
580
|
+
connect();
|
581
|
+
sendHeaders(defaultHeaders,
|
582
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
583
|
+
"PATH_INFO", "/custom_status",
|
584
|
+
"HTTP_X_CUSTOM_STATUS", "201 Bunnies Jump",
|
585
|
+
NULL);
|
586
|
+
string response = readAll(connection);
|
587
|
+
ensure(containsSubstring(response, "HTTP/1.1 201 Bunnies Jump\r\n"));
|
588
|
+
ensure(containsSubstring(response, "Status: 201 Bunnies Jump\r\n"));
|
589
|
+
}
|
590
|
+
|
591
|
+
TEST_METHOD(38) {
|
592
|
+
// If the application doesn't output a status line then it rejects the application response.
|
593
|
+
// TODO
|
594
|
+
}
|
595
|
+
|
596
|
+
TEST_METHOD(39) {
|
597
|
+
// Test handling of slow clients that can't receive response data fast enough (response buffering).
|
598
|
+
init();
|
599
|
+
connect();
|
600
|
+
sendHeaders(defaultHeaders,
|
601
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
602
|
+
"PATH_INFO", "/blob",
|
603
|
+
"HTTP_X_SIZE", "10485760",
|
604
|
+
NULL);
|
605
|
+
EVENTUALLY(10,
|
606
|
+
result = containsSubstring(inspect(), "appInput reachedEnd = true");
|
607
|
+
);
|
608
|
+
string result = stripHeaders(readAll(connection));
|
609
|
+
ensure_equals(result.size(), 10485760u);
|
610
|
+
const char *data = result.data();
|
611
|
+
const char *end = result.data() + result.size();
|
612
|
+
while (data < end) {
|
613
|
+
ensure_equals(*data, 'x');
|
614
|
+
data++;
|
615
|
+
}
|
616
|
+
}
|
617
|
+
|
618
|
+
TEST_METHOD(40) {
|
619
|
+
set_test_name("Test that RequestHandler does not read more than CONTENT_LENGTH bytes "
|
620
|
+
"from the client body (when buffering is on and request body is large).");
|
621
|
+
|
622
|
+
DeleteFileEventually d("/tmp/output.txt");
|
623
|
+
|
624
|
+
// 2.6 MB of request body. Guaranteed not to fit in any socket buffer.
|
625
|
+
string requestBody;
|
626
|
+
for (int i = 0; i < 204800; i++) {
|
627
|
+
requestBody.append("hello world!\n");
|
628
|
+
}
|
629
|
+
|
630
|
+
init();
|
631
|
+
connect();
|
632
|
+
sendHeaders(defaultHeaders,
|
633
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
634
|
+
"PATH_INFO", "/upload",
|
635
|
+
"CONTENT_LENGTH", toString(requestBody.size()).c_str(),
|
636
|
+
"PASSENGER_BUFFERING", "true",
|
637
|
+
"HTTP_X_OUTPUT", "/tmp/output.txt",
|
638
|
+
NULL);
|
639
|
+
writeExact(connection, requestBody);
|
640
|
+
|
641
|
+
string result = stripHeaders(readAll(connection));
|
642
|
+
ensure_equals(result, "ok");
|
643
|
+
struct stat buf;
|
644
|
+
ensure(stat("/tmp/output.txt", &buf) == 0);
|
645
|
+
ensure_equals(buf.st_size, (off_t) requestBody.size());
|
646
|
+
}
|
647
|
+
|
648
|
+
TEST_METHOD(41) {
|
649
|
+
set_test_name("Test that RequestHandler does not read more than CONTENT_LENGTH bytes "
|
650
|
+
"from the client body (when buffering is on and request body is small).");
|
651
|
+
|
652
|
+
DeleteFileEventually d("/tmp/output.txt");
|
653
|
+
string requestBody = "hello world";
|
654
|
+
|
655
|
+
init();
|
656
|
+
connect();
|
657
|
+
sendHeaders(defaultHeaders,
|
658
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
659
|
+
"PATH_INFO", "/upload",
|
660
|
+
"CONTENT_LENGTH", toString(requestBody.size()).c_str(),
|
661
|
+
"PASSENGER_BUFFERING", "true",
|
662
|
+
"HTTP_X_OUTPUT", "/tmp/output.txt",
|
663
|
+
NULL);
|
664
|
+
writeExact(connection, requestBody);
|
665
|
+
|
666
|
+
string result = stripHeaders(readAll(connection));
|
667
|
+
ensure_equals(result, "ok");
|
668
|
+
struct stat buf;
|
669
|
+
ensure(stat("/tmp/output.txt", &buf) == 0);
|
670
|
+
ensure_equals(buf.st_size, (off_t) requestBody.size());
|
671
|
+
}
|
672
|
+
|
673
|
+
TEST_METHOD(42) {
|
674
|
+
set_test_name("Test that RequestHandler does not read more than CONTENT_LENGTH bytes "
|
675
|
+
"from the client body (when buffering is off and request body is large).");
|
676
|
+
|
677
|
+
DeleteFileEventually d("/tmp/output.txt");
|
678
|
+
|
679
|
+
// 2 MB of request body. Guaranteed not to fit in any socket buffer.
|
680
|
+
string requestBody;
|
681
|
+
for (int i = 0; i < 102400; i++) {
|
682
|
+
char buf[100];
|
683
|
+
snprintf(buf, sizeof(buf), "%06d: hello world!\n", i);
|
684
|
+
requestBody.append(buf);
|
685
|
+
}
|
686
|
+
|
687
|
+
init();
|
688
|
+
connect();
|
689
|
+
sendHeaders(defaultHeaders,
|
690
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
691
|
+
"PATH_INFO", "/upload",
|
692
|
+
"CONTENT_LENGTH", toString(requestBody.size()).c_str(),
|
693
|
+
"HTTP_X_OUTPUT", "/tmp/output.txt",
|
694
|
+
NULL);
|
695
|
+
|
696
|
+
TempThread thr(boost::bind(RequestHandlerTest::writeBody, connection, requestBody));
|
697
|
+
|
698
|
+
string result = stripHeaders(readAll(connection));
|
699
|
+
ensure_equals(result, "ok");
|
700
|
+
struct stat buf;
|
701
|
+
ensure(stat("/tmp/output.txt", &buf) == 0);
|
702
|
+
ensure_equals(buf.st_size, (off_t) requestBody.size());
|
703
|
+
}
|
704
|
+
|
705
|
+
TEST_METHOD(43) {
|
706
|
+
set_test_name("Test that RequestHandler does not read more than CONTENT_LENGTH bytes "
|
707
|
+
"from the client body (when buffering is off and request body is small).");
|
708
|
+
|
709
|
+
DeleteFileEventually d("/tmp/output.txt");
|
710
|
+
string requestBody = "hello world";
|
711
|
+
|
712
|
+
init();
|
713
|
+
connect();
|
714
|
+
sendHeaders(defaultHeaders,
|
715
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
716
|
+
"PATH_INFO", "/upload",
|
717
|
+
"CONTENT_LENGTH", toString(requestBody.size()).c_str(),
|
718
|
+
"HTTP_X_OUTPUT", "/tmp/output.txt",
|
719
|
+
NULL);
|
720
|
+
|
721
|
+
TempThread thr(boost::bind(RequestHandlerTest::writeBody, connection, requestBody));
|
722
|
+
|
723
|
+
string result = stripHeaders(readAll(connection));
|
724
|
+
ensure_equals(result, "ok");
|
725
|
+
struct stat buf;
|
726
|
+
ensure(stat("/tmp/output.txt", &buf) == 0);
|
727
|
+
ensure_equals(buf.st_size, (off_t) requestBody.size());
|
728
|
+
}
|
729
|
+
|
730
|
+
TEST_METHOD(44) {
|
731
|
+
set_test_name("Test that RequestHandler does not pass any client body data when CONTENT_LENGTH == 0 (when buffering is on).");
|
732
|
+
|
733
|
+
DeleteFileEventually d("/tmp/output.txt");
|
734
|
+
|
735
|
+
init();
|
736
|
+
connect();
|
737
|
+
sendHeaders(defaultHeaders,
|
738
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
739
|
+
"PATH_INFO", "/upload",
|
740
|
+
"CONTENT_LENGTH", "0",
|
741
|
+
"PASSENGER_BUFFERING", "true",
|
742
|
+
"HTTP_X_OUTPUT", "/tmp/output.txt",
|
743
|
+
NULL);
|
744
|
+
writeExact(connection, "hello world");
|
745
|
+
|
746
|
+
string result = stripHeaders(readAll(connection));
|
747
|
+
ensure_equals(result, "ok");
|
748
|
+
struct stat buf;
|
749
|
+
ensure(stat("/tmp/output.txt", &buf) == 0);
|
750
|
+
ensure_equals(buf.st_size, (off_t) 0);
|
751
|
+
}
|
752
|
+
|
753
|
+
TEST_METHOD(45) {
|
754
|
+
set_test_name("Test that RequestHandler does not pass any client body data when CONTENT_LENGTH == 0 (when buffering is off).");
|
755
|
+
|
756
|
+
DeleteFileEventually d("/tmp/output.txt");
|
757
|
+
|
758
|
+
init();
|
759
|
+
connect();
|
760
|
+
sendHeaders(defaultHeaders,
|
761
|
+
"PASSENGER_APP_ROOT", wsgiAppPath.c_str(),
|
762
|
+
"PATH_INFO", "/upload",
|
763
|
+
"CONTENT_LENGTH", "0",
|
764
|
+
"HTTP_X_OUTPUT", "/tmp/output.txt",
|
765
|
+
NULL);
|
766
|
+
writeExact(connection, "hello world");
|
767
|
+
|
768
|
+
string result = stripHeaders(readAll(connection));
|
769
|
+
ensure_equals(result, "ok");
|
770
|
+
struct stat buf;
|
771
|
+
ensure(stat("/tmp/output.txt", &buf) == 0);
|
772
|
+
ensure_equals(buf.st_size, (off_t) 0);
|
773
|
+
}
|
774
|
+
|
775
|
+
// Test small response buffering.
|
776
|
+
// Test large response buffering.
|
777
|
+
}
|