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
@@ -1,5 +1,5 @@
|
|
1
1
|
# Phusion Passenger - http://www.modrails.com/
|
2
|
-
# Copyright (c) 2010 Phusion
|
2
|
+
# Copyright (c) 2010-2012 Phusion
|
3
3
|
#
|
4
4
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
5
5
|
#
|
@@ -56,6 +56,7 @@ class StartCommand < Command
|
|
56
56
|
parse_my_options
|
57
57
|
sanity_check_options
|
58
58
|
|
59
|
+
@runtime_dirs = determine_runtime_dirs
|
59
60
|
ensure_nginx_installed
|
60
61
|
determine_various_resource_locations
|
61
62
|
require_app_finder
|
@@ -155,10 +156,6 @@ private
|
|
155
156
|
wrap_desc("Enable rolling restarts (Enterprise only)")) do
|
156
157
|
@options[:rolling_restarts] = true
|
157
158
|
end
|
158
|
-
opts.on("--resist-deployment-errors",
|
159
|
-
wrap_desc("Enable deployment error resistance (Enterprise only)")) do
|
160
|
-
@options[:resist_deployment_errors] = true
|
161
|
-
end
|
162
159
|
opts.on("--union-station-gateway HOST:PORT", String,
|
163
160
|
wrap_desc("Specify Union Station Gateway host and port")) do |value|
|
164
161
|
host, port = value.split(":", 2)
|
@@ -214,6 +211,10 @@ private
|
|
214
211
|
"checked for binaries prior to a local build.")) do |value|
|
215
212
|
@options[:binaries_url_root] = value
|
216
213
|
end
|
214
|
+
opts.on("--runtime-dir DIRECTORY", String,
|
215
|
+
wrap_desc("Directory to use for Phusion Passenger Standalone runtime files")) do |value|
|
216
|
+
@options[:runtime_dir] = File.expand_path(value)
|
217
|
+
end
|
217
218
|
end
|
218
219
|
@plugin.call_hook(:done_parsing_options)
|
219
220
|
end
|
@@ -305,54 +306,58 @@ private
|
|
305
306
|
end
|
306
307
|
end
|
307
308
|
|
308
|
-
def install_runtime
|
309
|
+
def install_runtime(runtime_dirs)
|
309
310
|
require 'phusion_passenger/standalone/runtime_installer'
|
310
311
|
installer = RuntimeInstaller.new(
|
311
|
-
:
|
312
|
-
:support_dir =>
|
313
|
-
:nginx_dir => nginx_dir,
|
314
|
-
:
|
315
|
-
:
|
312
|
+
:targets => [:nginx, :ruby, :support_binaries],
|
313
|
+
:support_dir => runtime_dirs[:support_dir],
|
314
|
+
:nginx_dir => runtime_dirs[:nginx_dir],
|
315
|
+
:ruby_dir => runtime_dirs[:ruby_dir],
|
316
|
+
:nginx_version => @options[:nginx_version],
|
317
|
+
:nginx_tarball => @options[:nginx_tarball],
|
316
318
|
:binaries_url_root => @options[:binaries_url_root],
|
317
319
|
:plugin => @plugin)
|
318
|
-
installer.
|
320
|
+
installer.run
|
319
321
|
end
|
320
322
|
|
321
|
-
def
|
322
|
-
|
323
|
+
def determine_runtime_dirs
|
324
|
+
require_platform_info_binary_compatibility
|
325
|
+
if root = @options[:runtime_dir]
|
326
|
+
nginx_dir = determine_nginx_runtime_dir(root)
|
327
|
+
else
|
328
|
+
root = "#{GLOBAL_STANDALONE_RESOURCE_DIR}/#{PhusionPassenger::VERSION_STRING}"
|
329
|
+
nginx_dir = determine_nginx_runtime_dir(root)
|
330
|
+
if !File.exist?("#{nginx_dir}/nginx") && Process.euid != 0
|
331
|
+
home = Etc.getpwuid.dir
|
332
|
+
root = "#{home}/#{LOCAL_STANDALONE_RESOURCE_DIR}/#{PhusionPassenger::VERSION_STRING}"
|
333
|
+
nginx_dir = determine_nginx_runtime_dir(root)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
nginx_bin = @options[:nginx_bin] || "#{nginx_dir}/nginx"
|
337
|
+
return {
|
338
|
+
:root => root,
|
339
|
+
:support_dir => "#{root}/support-#{PlatformInfo.cxx_binary_compatibility_id}",
|
340
|
+
:nginx_dir => nginx_dir,
|
341
|
+
:ruby_dir => "#{root}/rubyext-#{PlatformInfo.ruby_extension_binary_compatibility_id}",
|
342
|
+
:nginx_installed => File.exist?(nginx_bin)
|
343
|
+
}
|
323
344
|
end
|
324
|
-
|
325
|
-
def
|
326
|
-
return "#{
|
345
|
+
|
346
|
+
def determine_nginx_runtime_dir(runtime_dir)
|
347
|
+
return "#{runtime_dir}/nginx-#{@options[:nginx_version]}-#{PlatformInfo.cxx_binary_compatibility_id}"
|
327
348
|
end
|
328
|
-
|
349
|
+
|
329
350
|
def ensure_nginx_installed
|
330
|
-
if
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
home = Etc.getpwuid.dir
|
336
|
-
@runtime_dir = "#{GLOBAL_STANDALONE_RESOURCE_DIR}/#{runtime_version_string}"
|
337
|
-
if !File.exist?("#{nginx_dir}/sbin/nginx")
|
338
|
-
if Process.euid == 0
|
339
|
-
install_runtime
|
351
|
+
if !@runtime_dirs[:nginx_installed]
|
352
|
+
if @options[:nginx_bin]
|
353
|
+
error "The given Nginx binary '#{@options[:nginx_bin]}' does not exist."
|
354
|
+
exit 1
|
340
355
|
else
|
341
|
-
@
|
342
|
-
if !File.exist?("#{nginx_dir}/sbin/nginx")
|
343
|
-
install_runtime
|
344
|
-
end
|
356
|
+
install_runtime(@runtime_dirs)
|
345
357
|
end
|
346
358
|
end
|
347
359
|
end
|
348
360
|
|
349
|
-
def ensure_directory_exists(dir)
|
350
|
-
if !File.exist?(dir)
|
351
|
-
require_file_utils
|
352
|
-
FileUtils.mkdir_p(dir)
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
361
|
def start_nginx
|
357
362
|
begin
|
358
363
|
@nginx.start
|
@@ -27,17 +27,17 @@ module Standalone
|
|
27
27
|
module Utils
|
28
28
|
private
|
29
29
|
def require_platform_info_binary_compatibility
|
30
|
-
if !defined?(PlatformInfo) || !PlatformInfo.respond_to?(:
|
30
|
+
if !defined?(PlatformInfo) || !PlatformInfo.respond_to?(:cxx_binary_compatibility_id)
|
31
31
|
require 'phusion_passenger/platform_info/binary_compatibility'
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def runtime_version_string
|
36
|
-
if PhusionPassenger.
|
37
|
-
return "natively-packaged"
|
38
|
-
else
|
35
|
+
def runtime_version_string(nginx_version)
|
36
|
+
if PhusionPassenger.originally_packaged? || nginx_version != PhusionPassenger::PREFERRED_NGINX_VERSION
|
39
37
|
require_platform_info_binary_compatibility
|
40
38
|
return "#{VERSION_STRING}-#{PlatformInfo.passenger_binary_compatibility_id}"
|
39
|
+
else
|
40
|
+
return VERSION_STRING
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: binary
|
2
2
|
# Phusion Passenger - http://www.modrails.com/
|
3
|
-
# Copyright (c) 2010 Phusion
|
3
|
+
# Copyright (c) 2010, 2011, 2012 Phusion
|
4
4
|
#
|
5
5
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
#
|
@@ -23,148 +23,43 @@
|
|
23
23
|
# THE SOFTWARE.
|
24
24
|
|
25
25
|
require 'rubygems'
|
26
|
-
require 'thread'
|
27
|
-
if (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby") && RUBY_VERSION < "1.8.7"
|
28
|
-
require 'fastthread'
|
29
|
-
end
|
30
|
-
require 'pathname'
|
31
|
-
require 'etc'
|
32
|
-
require 'fcntl'
|
33
|
-
require 'tempfile'
|
34
|
-
require 'timeout'
|
35
|
-
require 'stringio'
|
36
|
-
require 'phusion_passenger/exceptions'
|
37
26
|
require 'phusion_passenger/native_support'
|
38
27
|
|
39
28
|
module PhusionPassenger
|
40
29
|
|
41
30
|
# Utility functions.
|
42
31
|
module Utils
|
43
|
-
|
44
|
-
def private_class_method(name)
|
45
|
-
metaclass = class << self; self; end
|
46
|
-
metaclass.send(:private, name)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Return the canonicalized version of +path+. This path is guaranteed to
|
50
|
-
# to be "normal", i.e. it doesn't contain stuff like ".." or "/",
|
51
|
-
# and it fully resolves symbolic links.
|
52
|
-
#
|
53
|
-
# Raises SystemCallError if something went wrong. Raises ArgumentError
|
54
|
-
# if +path+ is nil. Raises InvalidPath if +path+ does not appear
|
55
|
-
# to be a valid path.
|
56
|
-
def canonicalize_path(path)
|
57
|
-
raise ArgumentError, "The 'path' argument may not be nil" if path.nil?
|
58
|
-
return Pathname.new(path).realpath.to_s
|
59
|
-
rescue Errno::ENOENT => e
|
60
|
-
raise InvalidPath, e.message
|
61
|
-
end
|
62
|
-
|
63
|
-
# Assert that +path+ is a directory. Raises +InvalidPath+ if it isn't.
|
64
|
-
def assert_valid_directory(path)
|
65
|
-
if !File.directory?(path)
|
66
|
-
raise InvalidPath, "'#{path}' is not a valid directory."
|
67
|
-
end
|
68
|
-
end
|
32
|
+
extend self # Make methods available as class methods.
|
69
33
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
34
|
+
def self.included(klass)
|
35
|
+
# When included into another class, make sure that Utils
|
36
|
+
# methods are made private.
|
37
|
+
public_instance_methods(false).each do |method_name|
|
38
|
+
klass.send(:private, method_name)
|
74
39
|
end
|
75
40
|
end
|
76
41
|
|
77
|
-
# Assert that +username+ is a valid username. Raises
|
78
|
-
# ArgumentError if that is not the case.
|
79
|
-
def assert_valid_username(username)
|
80
|
-
# If username does not exist then getpwnam() will raise an ArgumentError.
|
81
|
-
username && Etc.getpwnam(username)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Assert that +groupname+ is a valid group name. Raises
|
85
|
-
# ArgumentError if that is not the case.
|
86
|
-
def assert_valid_groupname(groupname)
|
87
|
-
# If groupname does not exist then getgrnam() will raise an ArgumentError.
|
88
|
-
groupname && Etc.getgrnam(groupname)
|
89
|
-
end
|
90
|
-
|
91
42
|
# Generate a long, cryptographically secure random ID string, which
|
92
43
|
# is also a valid filename.
|
93
44
|
def generate_random_id(method)
|
45
|
+
data = File.open("/dev/urandom", "rb") do |f|
|
46
|
+
f.read(64)
|
47
|
+
end
|
94
48
|
case method
|
95
49
|
when :base64
|
96
|
-
data = [
|
50
|
+
data = [data].pack('m')
|
97
51
|
data.gsub!("\n", '')
|
98
52
|
data.gsub!("+", '')
|
99
53
|
data.gsub!("/", '')
|
100
54
|
data.gsub!(/==$/, '')
|
101
55
|
return data
|
102
56
|
when :hex
|
103
|
-
return
|
57
|
+
return data.unpack('H*')[0]
|
104
58
|
else
|
105
59
|
raise ArgumentError, "Invalid method #{method.inspect}"
|
106
60
|
end
|
107
61
|
end
|
108
62
|
|
109
|
-
def close_all_io_objects_for_fds(file_descriptors_to_leave_open)
|
110
|
-
ObjectSpace.each_object(IO) do |io|
|
111
|
-
begin
|
112
|
-
if !file_descriptors_to_leave_open.include?(io.fileno) && !io.closed?
|
113
|
-
io.close
|
114
|
-
end
|
115
|
-
rescue
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def marshal_exception(exception)
|
121
|
-
data = {
|
122
|
-
:message => exception.message,
|
123
|
-
:class => exception.class.to_s,
|
124
|
-
:backtrace => exception.backtrace
|
125
|
-
}
|
126
|
-
if exception.is_a?(InitializationError)
|
127
|
-
data[:is_initialization_error] = true
|
128
|
-
if exception.child_exception
|
129
|
-
data[:child_exception] = marshal_exception(exception.child_exception)
|
130
|
-
child_exception = exception.child_exception
|
131
|
-
exception.child_exception = nil
|
132
|
-
data[:exception] = Marshal.dump(exception)
|
133
|
-
exception.child_exception = child_exception
|
134
|
-
end
|
135
|
-
else
|
136
|
-
begin
|
137
|
-
data[:exception] = Marshal.dump(exception)
|
138
|
-
rescue ArgumentError, TypeError
|
139
|
-
e = UnknownError.new(exception.message, exception.class.to_s,
|
140
|
-
exception.backtrace)
|
141
|
-
data[:exception] = Marshal.dump(e)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
return Marshal.dump(data)
|
145
|
-
end
|
146
|
-
|
147
|
-
def unmarshal_exception(data)
|
148
|
-
hash = Marshal.load(data)
|
149
|
-
if hash[:is_initialization_error]
|
150
|
-
if hash[:child_exception]
|
151
|
-
child_exception = unmarshal_exception(hash[:child_exception])
|
152
|
-
else
|
153
|
-
child_exception = nil
|
154
|
-
end
|
155
|
-
|
156
|
-
exception = Marshal.load(hash[:exception])
|
157
|
-
exception.child_exception = child_exception
|
158
|
-
return exception
|
159
|
-
else
|
160
|
-
begin
|
161
|
-
return Marshal.load(hash[:exception])
|
162
|
-
rescue ArgumentError, TypeError
|
163
|
-
return UnknownError.new(hash[:message], hash[:class], hash[:backtrace])
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
63
|
# Print the given exception, including the stack trace, to STDERR.
|
169
64
|
#
|
170
65
|
# +current_location+ is a string which describes where the code is
|
@@ -182,237 +77,6 @@ protected
|
|
182
77
|
end
|
183
78
|
end
|
184
79
|
|
185
|
-
# Prepare an application process using rules for the given spawn options.
|
186
|
-
# This method is to be called before loading the application code.
|
187
|
-
#
|
188
|
-
# +startup_file+ is the application type's startup file, e.g.
|
189
|
-
# "config/environment.rb" for Rails apps and "config.ru" for Rack apps.
|
190
|
-
# See SpawnManager#spawn_application for options.
|
191
|
-
#
|
192
|
-
# This function may modify +options+. The modified options are to be
|
193
|
-
# passed to the request handler.
|
194
|
-
def prepare_app_process(startup_file, options)
|
195
|
-
options["app_root"] = canonicalize_path(options["app_root"])
|
196
|
-
Dir.chdir(options["app_root"])
|
197
|
-
|
198
|
-
lower_privilege(startup_file, options)
|
199
|
-
path, is_parent = check_directory_tree_permissions(options["app_root"])
|
200
|
-
if path
|
201
|
-
username = Etc.getpwuid(Process.euid).name
|
202
|
-
groupname = Etc.getgrgid(Process.egid).name
|
203
|
-
message = "This application process is currently running as " +
|
204
|
-
"user '#{username}' and group '#{groupname}' and must be " +
|
205
|
-
"able to access its application root directory " +
|
206
|
-
"'#{options["app_root"]}'. "
|
207
|
-
if is_parent
|
208
|
-
message << "However the parent directory '#{path}' " +
|
209
|
-
"has wrong permissions, thereby preventing " +
|
210
|
-
"this process from accessing its application " +
|
211
|
-
"root directory. Please fix the permissions " +
|
212
|
-
"of the directory '#{path}' first."
|
213
|
-
else
|
214
|
-
message << "However this directory is not accessible " +
|
215
|
-
"because it has wrong permissions. Please fix " +
|
216
|
-
"these permissions first."
|
217
|
-
end
|
218
|
-
raise(message)
|
219
|
-
end
|
220
|
-
|
221
|
-
ENV["RAILS_ENV"] = ENV["RACK_ENV"] = options["environment"]
|
222
|
-
|
223
|
-
base_uri = options["base_uri"]
|
224
|
-
if base_uri && !base_uri.empty? && base_uri != "/"
|
225
|
-
ENV["RAILS_RELATIVE_URL_ROOT"] = base_uri
|
226
|
-
ENV["RACK_BASE_URI"] = base_uri
|
227
|
-
end
|
228
|
-
|
229
|
-
encoded_environment_variables = options["environment_variables"]
|
230
|
-
if encoded_environment_variables
|
231
|
-
env_vars_string = encoded_environment_variables.unpack("m").first
|
232
|
-
env_vars_array = env_vars_string.split("\0", -1)
|
233
|
-
env_vars_array.pop
|
234
|
-
env_vars = Hash[*env_vars_array]
|
235
|
-
env_vars.each_pair do |key, value|
|
236
|
-
ENV[key] = value
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
# Instantiate the analytics logger if requested. Can be nil.
|
241
|
-
require 'phusion_passenger/analytics_logger'
|
242
|
-
options["analytics_logger"] = AnalyticsLogger.new_from_options(options)
|
243
|
-
|
244
|
-
# Make sure RubyGems uses any new environment variable values
|
245
|
-
# that have been set now (e.g. $HOME, $GEM_HOME, etc) and that
|
246
|
-
# it is able to detect newly installed gems.
|
247
|
-
Gem.clear_paths
|
248
|
-
|
249
|
-
# Because spawned app processes exit using #exit!, #at_exit
|
250
|
-
# blocks aren't called. Here we ninja patch Kernel so that
|
251
|
-
# we can call #at_exit blocks during app process shutdown.
|
252
|
-
class << Kernel
|
253
|
-
def passenger_call_at_exit_blocks
|
254
|
-
@passenger_at_exit_blocks ||= []
|
255
|
-
@passenger_at_exit_blocks.reverse_each do |block|
|
256
|
-
block.call
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
def passenger_at_exit(&block)
|
261
|
-
@passenger_at_exit_blocks ||= []
|
262
|
-
@passenger_at_exit_blocks << block
|
263
|
-
return block
|
264
|
-
end
|
265
|
-
end
|
266
|
-
Kernel.class_eval do
|
267
|
-
def at_exit(&block)
|
268
|
-
return Kernel.passenger_at_exit(&block)
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
|
273
|
-
# Rack::ApplicationSpawner depends on the 'rack' library, but the app
|
274
|
-
# might want us to use a bundled version instead of a
|
275
|
-
# gem/apt-get/yum/whatever-installed version. Therefore we must setup
|
276
|
-
# the correct load paths before requiring 'rack'.
|
277
|
-
#
|
278
|
-
# The most popular tool for bundling dependencies is Bundler. Bundler
|
279
|
-
# works as follows:
|
280
|
-
# - If the bundle is locked then a file .bundle/environment.rb exists
|
281
|
-
# which will setup the load paths.
|
282
|
-
# - If the bundle is not locked then the load paths must be set up by
|
283
|
-
# calling Bundler.setup.
|
284
|
-
# - Rails 3's boot.rb automatically loads .bundle/environment.rb or
|
285
|
-
# calls Bundler.setup if that's not available.
|
286
|
-
# - Other Rack apps might not have a boot.rb but we still want to setup
|
287
|
-
# Bundler.
|
288
|
-
# - Some Rails 2 apps might have explicitly added Bundler support.
|
289
|
-
# These apps call Bundler.setup in their preinitializer.rb.
|
290
|
-
#
|
291
|
-
# So the strategy is as follows:
|
292
|
-
|
293
|
-
# Our strategy might be completely unsuitable for the app or the
|
294
|
-
# developer is using something other than Bundler, so we let the user
|
295
|
-
# manually specify a load path setup file.
|
296
|
-
if options["load_path_setup_file"]
|
297
|
-
require File.expand_path(options["load_path_setup_file"])
|
298
|
-
|
299
|
-
# The app developer may also override our strategy with this magic file.
|
300
|
-
elsif File.exist?('config/setup_load_paths.rb')
|
301
|
-
require File.expand_path('config/setup_load_paths')
|
302
|
-
|
303
|
-
# If the Bundler lock environment file exists then load that. If it
|
304
|
-
# exists then there's a 99.9% chance that loading it is the correct
|
305
|
-
# thing to do.
|
306
|
-
elsif File.exist?('.bundle/environment.rb')
|
307
|
-
require File.expand_path('.bundle/environment')
|
308
|
-
|
309
|
-
# If the Bundler environment file doesn't exist then there are two
|
310
|
-
# possibilities:
|
311
|
-
# 1. Bundler is not used, in which case we don't have to do anything.
|
312
|
-
# 2. Bundler *is* used, but the gems are not locked and we're supposed
|
313
|
-
# to call Bundler.setup.
|
314
|
-
#
|
315
|
-
# The existence of Gemfile indicates whether (2) is true:
|
316
|
-
elsif File.exist?('Gemfile')
|
317
|
-
# In case of Rails 3, config/boot.rb already calls Bundler.setup.
|
318
|
-
# However older versions of Rails may not so loading boot.rb might
|
319
|
-
# not be the correct thing to do. To be on the safe side we
|
320
|
-
# call Bundler.setup ourselves; calling Bundler.setup twice is
|
321
|
-
# harmless. If this isn't the correct thing to do after all then
|
322
|
-
# there's always the load_path_setup_file option and
|
323
|
-
# setup_load_paths.rb.
|
324
|
-
require 'rubygems'
|
325
|
-
require 'bundler'
|
326
|
-
Bundler.setup
|
327
|
-
end
|
328
|
-
|
329
|
-
# Bundler might remove Phusion Passenger from the load path in its zealous
|
330
|
-
# attempt to un-require RubyGems, so here we put Phusion Passenger back
|
331
|
-
# into the load path. This must be done before loading the app's startup
|
332
|
-
# file because the app might require() Phusion Passenger files.
|
333
|
-
if !$LOAD_PATH.include?(LIBDIR)
|
334
|
-
$LOAD_PATH.unshift(LIBDIR)
|
335
|
-
$LOAD_PATH.uniq!
|
336
|
-
end
|
337
|
-
|
338
|
-
|
339
|
-
# !!! NOTE !!!
|
340
|
-
# If the app is using Bundler then any dependencies required past this
|
341
|
-
# point must be specified in the Gemfile. Like ruby-debug if debugging is on...
|
342
|
-
|
343
|
-
PhusionPassenger._spawn_options = options
|
344
|
-
end
|
345
|
-
|
346
|
-
# This method is to be called after loading the application code but
|
347
|
-
# before forking a worker process.
|
348
|
-
def after_loading_app_code(options)
|
349
|
-
# Even though prepare_app_process() restores the Phusion Passenger
|
350
|
-
# load path after setting up Bundler, the app itself might also
|
351
|
-
# remove Phusion Passenger from the load path for whatever reason,
|
352
|
-
# so here we restore the load path again.
|
353
|
-
if !$LOAD_PATH.include?(LIBDIR)
|
354
|
-
$LOAD_PATH.unshift(LIBDIR)
|
355
|
-
$LOAD_PATH.uniq!
|
356
|
-
end
|
357
|
-
|
358
|
-
# Post-install framework extensions. Possibly preceded by a call to
|
359
|
-
# PhusionPassenger.install_framework_extensions!
|
360
|
-
require 'rails/version' if defined?(::Rails) && !defined?(::Rails::VERSION)
|
361
|
-
if defined?(::Rails) && ::Rails::VERSION::MAJOR <= 2
|
362
|
-
require 'phusion_passenger/classic_rails_extensions/init'
|
363
|
-
ClassicRailsExtensions.init!(options)
|
364
|
-
# Rails 3 extensions are installed by
|
365
|
-
# PhusionPassenger.install_framework_extensions!
|
366
|
-
end
|
367
|
-
|
368
|
-
PhusionPassenger._spawn_options = nil
|
369
|
-
end
|
370
|
-
|
371
|
-
# To be called before the request handler main loop is entered, but after the app
|
372
|
-
# startup file has been loaded. This function will fire off necessary events
|
373
|
-
# and perform necessary preparation tasks.
|
374
|
-
#
|
375
|
-
# +forked+ indicates whether the current worker process is forked off from
|
376
|
-
# an ApplicationSpawner that has preloaded the app code.
|
377
|
-
# +options+ are the spawn options that were passed.
|
378
|
-
def before_handling_requests(forked, options)
|
379
|
-
if forked && options["analytics_logger"]
|
380
|
-
options["analytics_logger"].clear_connection
|
381
|
-
end
|
382
|
-
|
383
|
-
# If we were forked from a preloader process then clear or
|
384
|
-
# re-establish ActiveRecord database connections. This prevents
|
385
|
-
# child processes from concurrently accessing the same
|
386
|
-
# database connection handles.
|
387
|
-
if forked && defined?(::ActiveRecord::Base)
|
388
|
-
if ::ActiveRecord::Base.respond_to?(:clear_all_connections!)
|
389
|
-
::ActiveRecord::Base.clear_all_connections!
|
390
|
-
elsif ::ActiveRecord::Base.respond_to?(:clear_active_connections!)
|
391
|
-
::ActiveRecord::Base.clear_active_connections!
|
392
|
-
elsif ::ActiveRecord::Base.respond_to?(:connected?) &&
|
393
|
-
::ActiveRecord::Base.connected?
|
394
|
-
::ActiveRecord::Base.establish_connection
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
# Fire off events.
|
399
|
-
PhusionPassenger.call_event(:starting_worker_process, forked)
|
400
|
-
if options["pool_account_username"] && options["pool_account_password_base64"]
|
401
|
-
password = options["pool_account_password_base64"].unpack('m').first
|
402
|
-
PhusionPassenger.call_event(:credentials,
|
403
|
-
options["pool_account_username"], password)
|
404
|
-
else
|
405
|
-
PhusionPassenger.call_event(:credentials, nil, nil)
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
|
-
# To be called after the request handler main loop is exited. This function
|
410
|
-
# will fire off necessary events perform necessary cleanup tasks.
|
411
|
-
def after_handling_requests
|
412
|
-
PhusionPassenger.call_event(:stopping_worker_process)
|
413
|
-
Kernel.passenger_call_at_exit_blocks
|
414
|
-
end
|
415
|
-
|
416
80
|
def get_socket_address_type(address)
|
417
81
|
if address =~ %r{^unix:.}
|
418
82
|
return :unix
|
@@ -448,47 +112,6 @@ protected
|
|
448
112
|
end
|
449
113
|
end
|
450
114
|
|
451
|
-
# Fork a new process and run the given block inside the child process, just like
|
452
|
-
# fork(). Unlike fork(), this method is safe, i.e. there's no way for the child
|
453
|
-
# process to escape the block. Any uncaught exceptions in the child process will
|
454
|
-
# be printed to standard output, citing +current_location+ as the source.
|
455
|
-
# Futhermore, the child process will exit by calling Kernel#exit!, thereby
|
456
|
-
# bypassing any at_exit or ensure blocks.
|
457
|
-
#
|
458
|
-
# If +double_fork+ is true, then the child process will fork and immediately exit.
|
459
|
-
# This technique can be used to avoid zombie processes, at the expense of not
|
460
|
-
# being able to waitpid() the second child.
|
461
|
-
def safe_fork(current_location = self.class, double_fork = false)
|
462
|
-
pid = fork
|
463
|
-
if pid.nil?
|
464
|
-
has_exception = false
|
465
|
-
begin
|
466
|
-
if double_fork
|
467
|
-
pid2 = fork
|
468
|
-
if pid2.nil?
|
469
|
-
srand
|
470
|
-
yield
|
471
|
-
end
|
472
|
-
else
|
473
|
-
srand
|
474
|
-
yield
|
475
|
-
end
|
476
|
-
rescue Exception => e
|
477
|
-
has_exception = true
|
478
|
-
print_exception(current_location.to_s, e)
|
479
|
-
ensure
|
480
|
-
exit!(has_exception ? 1 : 0)
|
481
|
-
end
|
482
|
-
else
|
483
|
-
if double_fork
|
484
|
-
Process.waitpid(pid) rescue nil
|
485
|
-
return pid
|
486
|
-
else
|
487
|
-
return pid
|
488
|
-
end
|
489
|
-
end
|
490
|
-
end
|
491
|
-
|
492
115
|
# Checks whether the given process exists.
|
493
116
|
def process_is_alive?(pid)
|
494
117
|
begin
|
@@ -500,273 +123,18 @@ protected
|
|
500
123
|
return true
|
501
124
|
end
|
502
125
|
end
|
503
|
-
module_function :process_is_alive?
|
504
|
-
|
505
|
-
# Wraps another IO object. Everything written to the PseudoIO will
|
506
|
-
# not only be immediately forwarded to the underlying IO object but
|
507
|
-
# will also be captured in a buffer. The contents of the buffer
|
508
|
-
# can be retrieved by calling #done!.
|
509
|
-
class PseudoIO
|
510
|
-
def initialize(sink)
|
511
|
-
@sink = sink || File.open("/dev/null", "w")
|
512
|
-
@buffer = StringIO.new
|
513
|
-
end
|
514
|
-
|
515
|
-
def done!
|
516
|
-
result = @buffer.string
|
517
|
-
@buffer = nil
|
518
|
-
return result
|
519
|
-
end
|
520
|
-
|
521
|
-
def to_io
|
522
|
-
return self
|
523
|
-
end
|
524
|
-
|
525
|
-
def method_missing(*args, &block)
|
526
|
-
@buffer.send(*args, &block) if @buffer && args.first != :reopen
|
527
|
-
return @sink.send(*args, &block)
|
528
|
-
end
|
529
|
-
|
530
|
-
def respond_to?(symbol, include_private = false)
|
531
|
-
return @sink.respond_to?(symbol, include_private)
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
|
-
# Run the given block. A message will be sent through +channel+ (a
|
536
|
-
# MessageChannel object), telling the remote side whether the block
|
537
|
-
# raised an exception, called exit(), or succeeded.
|
538
|
-
#
|
539
|
-
# If _sink_ is non-nil, then every operation on $stderr/STDERR inside
|
540
|
-
# the block will be performed on _sink_ as well. If _sink_ is nil
|
541
|
-
# then all operations on $stderr/STDERR inside the block will be
|
542
|
-
# silently discarded, i.e. if one writes to $stderr/STDERR then nothing
|
543
|
-
# will be actually written to the console.
|
544
|
-
#
|
545
|
-
# Returns whether the block succeeded, i.e. whether it didn't raise an
|
546
|
-
# exception.
|
547
|
-
#
|
548
|
-
# Exceptions are not propagated, except SystemExit and a few
|
549
|
-
# non-StandardExeption classes such as SignalException. Of the
|
550
|
-
# exceptions that are propagated, only SystemExit will be reported.
|
551
|
-
def report_app_init_status(channel, sink = STDERR)
|
552
|
-
begin
|
553
|
-
old_global_stderr = $stderr
|
554
|
-
old_stderr = STDERR
|
555
|
-
stderr_output = ""
|
556
|
-
|
557
|
-
pseudo_stderr = PseudoIO.new(sink)
|
558
|
-
Object.send(:remove_const, 'STDERR') rescue nil
|
559
|
-
Object.const_set('STDERR', pseudo_stderr)
|
560
|
-
$stderr = pseudo_stderr
|
561
|
-
|
562
|
-
begin
|
563
|
-
yield
|
564
|
-
ensure
|
565
|
-
Object.send(:remove_const, 'STDERR') rescue nil
|
566
|
-
Object.const_set('STDERR', old_stderr)
|
567
|
-
$stderr = old_global_stderr
|
568
|
-
stderr_output = pseudo_stderr.done!
|
569
|
-
end
|
570
|
-
|
571
|
-
channel.write('success')
|
572
|
-
return true
|
573
|
-
rescue StandardError, ScriptError, NoMemoryError => e
|
574
|
-
channel.write('exception')
|
575
|
-
channel.write_scalar(marshal_exception(e))
|
576
|
-
channel.write_scalar(stderr_output)
|
577
|
-
return false
|
578
|
-
rescue SystemExit => e
|
579
|
-
channel.write('exit')
|
580
|
-
channel.write_scalar(marshal_exception(e))
|
581
|
-
channel.write_scalar(stderr_output)
|
582
|
-
raise
|
583
|
-
end
|
584
|
-
end
|
585
|
-
|
586
|
-
# Receive status information that was sent to +channel+ by
|
587
|
-
# report_app_init_status. If an error occured according to the
|
588
|
-
# received information, then an appropriate exception will be
|
589
|
-
# raised.
|
590
|
-
#
|
591
|
-
# If <tt>print_exception</tt> evaluates to true, then the
|
592
|
-
# exception message and the backtrace will also be printed.
|
593
|
-
# Where it is printed to depends on the type of
|
594
|
-
# <tt>print_exception</tt>:
|
595
|
-
# - If it responds to #puts, then the exception information will
|
596
|
-
# be printed using this method.
|
597
|
-
# - If it responds to #to_str, then the exception information
|
598
|
-
# will be appended to the file whose filename equals the return
|
599
|
-
# value of the #to_str call.
|
600
|
-
# - Otherwise, it will be printed to STDERR.
|
601
|
-
#
|
602
|
-
# Raises:
|
603
|
-
# - AppInitError: this class wraps the exception information
|
604
|
-
# received through the channel.
|
605
|
-
# - IOError, SystemCallError, SocketError: these errors are
|
606
|
-
# raised if an error occurred while receiving the information
|
607
|
-
# through the channel.
|
608
|
-
def unmarshal_and_raise_errors(channel, print_exception = nil, app_type = "rails")
|
609
|
-
args = channel.read
|
610
|
-
if args.nil?
|
611
|
-
raise EOFError, "Unexpected end-of-file detected."
|
612
|
-
end
|
613
|
-
status = args[0]
|
614
|
-
if status == 'exception'
|
615
|
-
child_exception = unmarshal_exception(channel.read_scalar)
|
616
|
-
stderr = channel.read_scalar
|
617
|
-
exception = AppInitError.new(
|
618
|
-
"Application '#{@app_root}' raised an exception: " <<
|
619
|
-
"#{child_exception.class} (#{child_exception.message})",
|
620
|
-
child_exception,
|
621
|
-
app_type,
|
622
|
-
stderr.empty? ? nil : stderr)
|
623
|
-
elsif status == 'exit'
|
624
|
-
child_exception = unmarshal_exception(channel.read_scalar)
|
625
|
-
stderr = channel.read_scalar
|
626
|
-
exception = AppInitError.new("Application '#{@app_root}' exited during startup",
|
627
|
-
child_exception, app_type, stderr.empty? ? nil : stderr)
|
628
|
-
else
|
629
|
-
exception = nil
|
630
|
-
end
|
631
|
-
|
632
|
-
if print_exception && exception
|
633
|
-
if print_exception.respond_to?(:puts)
|
634
|
-
print_exception(self.class.to_s, child_exception, print_exception)
|
635
|
-
elsif print_exception.respond_to?(:to_str)
|
636
|
-
filename = print_exception.to_str
|
637
|
-
File.open(filename, 'a') do |f|
|
638
|
-
print_exception(self.class.to_s, child_exception, f)
|
639
|
-
end
|
640
|
-
else
|
641
|
-
print_exception(self.class.to_s, child_exception)
|
642
|
-
end
|
643
|
-
end
|
644
|
-
raise exception if exception
|
645
|
-
end
|
646
|
-
|
647
|
-
# No-op, hook for unit tests.
|
648
|
-
def self.lower_privilege_called
|
649
|
-
end
|
650
|
-
|
651
|
-
# Lowers the current process's privilege based on the documented rules for
|
652
|
-
# the "user", "group", "default_user" and "default_group" options.
|
653
|
-
def lower_privilege(startup_file, options)
|
654
|
-
Utils.lower_privilege_called
|
655
|
-
return if Process.euid != 0
|
656
|
-
|
657
|
-
if options["default_user"] && !options["default_user"].empty?
|
658
|
-
default_user = options["default_user"]
|
659
|
-
else
|
660
|
-
default_user = "nobody"
|
661
|
-
end
|
662
|
-
if options["default_group"] && !options["default_group"].empty?
|
663
|
-
default_group = options["default_group"]
|
664
|
-
else
|
665
|
-
default_group = Etc.getgrgid(Etc.getpwnam(default_user).gid).name
|
666
|
-
end
|
667
126
|
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
rescue ArgumentError
|
672
|
-
user_info = nil
|
673
|
-
end
|
127
|
+
def require_option(hash, key)
|
128
|
+
if hash.has_key?(key)
|
129
|
+
return hash[key]
|
674
130
|
else
|
675
|
-
|
676
|
-
begin
|
677
|
-
user_info = Etc.getpwuid(uid)
|
678
|
-
rescue ArgumentError
|
679
|
-
user_info = nil
|
680
|
-
end
|
681
|
-
end
|
682
|
-
if !user_info || user_info.uid == 0
|
683
|
-
begin
|
684
|
-
user_info = Etc.getpwnam(default_user)
|
685
|
-
rescue ArgumentError
|
686
|
-
user_info = nil
|
687
|
-
end
|
131
|
+
raise ArgumentError, "Option #{key.inspect} required"
|
688
132
|
end
|
689
|
-
|
690
|
-
if options["group"] && !options["group"].empty?
|
691
|
-
if options["group"] == "!STARTUP_FILE!"
|
692
|
-
gid = File.lstat(startup_file).gid
|
693
|
-
begin
|
694
|
-
group_info = Etc.getgrgid(gid)
|
695
|
-
rescue ArgumentError
|
696
|
-
group_info = nil
|
697
|
-
end
|
698
|
-
else
|
699
|
-
begin
|
700
|
-
group_info = Etc.getgrnam(options["group"])
|
701
|
-
rescue ArgumentError
|
702
|
-
group_info = nil
|
703
|
-
end
|
704
|
-
end
|
705
|
-
elsif user_info
|
706
|
-
begin
|
707
|
-
group_info = Etc.getgrgid(user_info.gid)
|
708
|
-
rescue ArgumentError
|
709
|
-
group_info = nil
|
710
|
-
end
|
711
|
-
else
|
712
|
-
group_info = nil
|
713
|
-
end
|
714
|
-
if !group_info || group_info.gid == 0
|
715
|
-
begin
|
716
|
-
group_info = Etc.getgrnam(default_group)
|
717
|
-
rescue ArgumentError
|
718
|
-
group_info = nil
|
719
|
-
end
|
720
|
-
end
|
721
|
-
|
722
|
-
if !user_info
|
723
|
-
raise SecurityError, "Cannot determine a user to lower privilege to"
|
724
|
-
end
|
725
|
-
if !group_info
|
726
|
-
raise SecurityError, "Cannot determine a group to lower privilege to"
|
727
|
-
end
|
728
|
-
|
729
|
-
NativeSupport.switch_user(user_info.name, user_info.uid, group_info.gid)
|
730
|
-
ENV['USER'] = user_info.name
|
731
|
-
ENV['HOME'] = user_info.dir
|
732
133
|
end
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
# +dir+ must be a canonical path.
|
738
|
-
#
|
739
|
-
# If one of the parent directories has wrong permissions, causing
|
740
|
-
# +dir+ to be inaccessible by the current process, then this function
|
741
|
-
# returns [path, true] where +path+ is the path of the top-most
|
742
|
-
# directory with wrong permissions.
|
743
|
-
#
|
744
|
-
# If +dir+ itself is not executable by the current process then
|
745
|
-
# this function returns [dir, false].
|
746
|
-
#
|
747
|
-
# Otherwise, nil is returned.
|
748
|
-
def check_directory_tree_permissions(dir)
|
749
|
-
components = dir.split("/")
|
750
|
-
components.shift
|
751
|
-
i = 0
|
752
|
-
# We can't use File.readable() and friends here because they
|
753
|
-
# don't always work right with ACLs. Instead of we use 'real'
|
754
|
-
# checks.
|
755
|
-
while i < components.size
|
756
|
-
path = "/" + components[0..i].join("/")
|
757
|
-
begin
|
758
|
-
File.stat(path)
|
759
|
-
rescue Errno::EACCES
|
760
|
-
return [File.dirname(path), true]
|
761
|
-
end
|
762
|
-
i += 1
|
763
|
-
end
|
764
|
-
begin
|
765
|
-
Dir.chdir(dir) do
|
766
|
-
return nil
|
767
|
-
end
|
768
|
-
rescue Errno::EACCES
|
769
|
-
return [dir, false]
|
134
|
+
|
135
|
+
def install_options_as_ivars(object, options, *keys)
|
136
|
+
keys.each do |key|
|
137
|
+
object.instance_variable_set("@#{key}", options[key])
|
770
138
|
end
|
771
139
|
end
|
772
140
|
|
@@ -774,10 +142,22 @@ protected
|
|
774
142
|
# or if that's not supported the backtrace for the current thread.
|
775
143
|
def global_backtrace_report
|
776
144
|
if Kernel.respond_to?(:caller_for_all_threads)
|
777
|
-
|
778
|
-
|
145
|
+
all_thread_stacks = caller_for_all_threads
|
146
|
+
elsif Thread.respond_to?(:list) && Thread.public_method_defined?(:backtrace)
|
147
|
+
all_thread_stacks = {}
|
148
|
+
Thread.list.each do |thread|
|
149
|
+
all_thread_stacks[thread] = thread.backtrace
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
output = "========== Process #{Process.pid}: backtrace dump ==========\n"
|
154
|
+
if all_thread_stacks
|
155
|
+
all_thread_stacks.each_pair do |thread, stack|
|
156
|
+
if thread_name = thread[:name]
|
157
|
+
thread_name = "(#{thread_name})"
|
158
|
+
end
|
779
159
|
output << ("-" * 60) << "\n"
|
780
|
-
output << "# Thread: #{thread.inspect}, "
|
160
|
+
output << "# Thread: #{thread.inspect}#{thread_name}, "
|
781
161
|
if thread == Thread.main
|
782
162
|
output << "[main thread], "
|
783
163
|
end
|
@@ -790,7 +170,6 @@ protected
|
|
790
170
|
output << "\n\n"
|
791
171
|
end
|
792
172
|
else
|
793
|
-
output = "========== Process #{Process.pid}: backtrace dump ==========\n"
|
794
173
|
output << ("-" * 60) << "\n"
|
795
174
|
output << "# Current thread: #{Thread.current.inspect}\n"
|
796
175
|
output << ("-" * 60) << "\n"
|
@@ -799,39 +178,6 @@ protected
|
|
799
178
|
return output
|
800
179
|
end
|
801
180
|
|
802
|
-
def to_boolean(value)
|
803
|
-
return !(value.nil? || value == false || value == "false")
|
804
|
-
end
|
805
|
-
|
806
|
-
def sanitize_spawn_options(options)
|
807
|
-
defaults = {
|
808
|
-
"app_type" => "rails",
|
809
|
-
"environment" => "production",
|
810
|
-
"spawn_method" => "smart-lv2",
|
811
|
-
"framework_spawner_timeout" => -1,
|
812
|
-
"app_spawner_timeout" => -1,
|
813
|
-
"print_exceptions" => true
|
814
|
-
}
|
815
|
-
options = defaults.merge(options)
|
816
|
-
options["app_group_name"] = options["app_root"] if !options["app_group_name"]
|
817
|
-
options["framework_spawner_timeout"] = options["framework_spawner_timeout"].to_i
|
818
|
-
options["app_spawner_timeout"] = options["app_spawner_timeout"].to_i
|
819
|
-
if options.has_key?("print_framework_loading_exceptions")
|
820
|
-
options["print_framework_loading_exceptions"] = to_boolean(options["print_framework_loading_exceptions"])
|
821
|
-
end
|
822
|
-
# Force this to be a boolean for easy use with Utils#unmarshal_and_raise_errors.
|
823
|
-
options["print_exceptions"] = to_boolean(options["print_exceptions"])
|
824
|
-
|
825
|
-
options["analytics"] = to_boolean(options["analytics"])
|
826
|
-
options["show_version_in_header"] = to_boolean(options["show_version_in_header"])
|
827
|
-
|
828
|
-
# Smart spawning is not supported when using ruby-debug.
|
829
|
-
options["debugger"] = to_boolean(options["debugger"])
|
830
|
-
options["spawn_method"] = "conservative" if options["debugger"]
|
831
|
-
|
832
|
-
return options
|
833
|
-
end
|
834
|
-
|
835
181
|
if defined?(PhusionPassenger::NativeSupport)
|
836
182
|
# Split the given string into an hash. Keys and values are obtained by splitting the
|
837
183
|
# string using the null character as the delimitor.
|
@@ -852,228 +198,3 @@ protected
|
|
852
198
|
end
|
853
199
|
|
854
200
|
end # module PhusionPassenger
|
855
|
-
|
856
|
-
class Exception
|
857
|
-
def backtrace_string(current_location = nil)
|
858
|
-
if current_location.nil?
|
859
|
-
location = nil
|
860
|
-
else
|
861
|
-
location = "in #{current_location} "
|
862
|
-
end
|
863
|
-
return "*** Exception #{self.class} #{location}" <<
|
864
|
-
"(#{self}) (process #{$$}, thread #{Thread.current}):\n" <<
|
865
|
-
"\tfrom " << backtrace.join("\n\tfrom ")
|
866
|
-
end
|
867
|
-
end
|
868
|
-
|
869
|
-
class ConditionVariable
|
870
|
-
# This is like ConditionVariable.wait(), but allows one to wait a maximum
|
871
|
-
# amount of time. Returns true if this condition was signaled, false if a
|
872
|
-
# timeout occurred.
|
873
|
-
def timed_wait(mutex, secs)
|
874
|
-
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
|
875
|
-
if secs > 100000000
|
876
|
-
# NOTE: If one calls timeout() on FreeBSD 5 with an
|
877
|
-
# argument of more than 100000000, then MRI will become
|
878
|
-
# stuck in an infite loop, blocking all threads. It seems
|
879
|
-
# that MRI uses select() to implement sleeping.
|
880
|
-
# I think that a value of more than 100000000 overflows
|
881
|
-
# select()'s data structures, causing it to behave incorrectly.
|
882
|
-
# So we just make sure we can't sleep more than 100000000
|
883
|
-
# seconds.
|
884
|
-
secs = 100000000
|
885
|
-
end
|
886
|
-
if ruby_engine == "jruby"
|
887
|
-
if secs > 0
|
888
|
-
return wait(mutex, secs)
|
889
|
-
else
|
890
|
-
return wait(mutex)
|
891
|
-
end
|
892
|
-
elsif RUBY_VERSION >= '1.9.2'
|
893
|
-
if secs > 0
|
894
|
-
t1 = Time.now
|
895
|
-
wait(mutex, secs)
|
896
|
-
t2 = Time.now
|
897
|
-
return t2.to_f - t1.to_f < secs
|
898
|
-
else
|
899
|
-
wait(mutex)
|
900
|
-
return true
|
901
|
-
end
|
902
|
-
else
|
903
|
-
if secs > 0
|
904
|
-
Timeout.timeout(secs) do
|
905
|
-
wait(mutex)
|
906
|
-
end
|
907
|
-
else
|
908
|
-
wait(mutex)
|
909
|
-
end
|
910
|
-
return true
|
911
|
-
end
|
912
|
-
rescue Timeout::Error
|
913
|
-
return false
|
914
|
-
end
|
915
|
-
|
916
|
-
# This is like ConditionVariable.wait(), but allows one to wait a maximum
|
917
|
-
# amount of time. Raises Timeout::Error if the timeout has elapsed.
|
918
|
-
def timed_wait!(mutex, secs)
|
919
|
-
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
|
920
|
-
if secs > 100000000
|
921
|
-
# See the corresponding note for timed_wait().
|
922
|
-
secs = 100000000
|
923
|
-
end
|
924
|
-
if ruby_engine == "jruby"
|
925
|
-
if secs > 0
|
926
|
-
if !wait(mutex, secs)
|
927
|
-
raise Timeout::Error, "Timeout"
|
928
|
-
end
|
929
|
-
else
|
930
|
-
wait(mutex)
|
931
|
-
end
|
932
|
-
elsif RUBY_VERSION >= '1.9.2'
|
933
|
-
if secs > 0
|
934
|
-
t1 = Time.now
|
935
|
-
wait(mutex, secs)
|
936
|
-
t2 = Time.now
|
937
|
-
if t2.to_f - t1.to_f >= secs
|
938
|
-
raise Timeout::Error, "Timeout"
|
939
|
-
end
|
940
|
-
else
|
941
|
-
wait(mutex)
|
942
|
-
end
|
943
|
-
else
|
944
|
-
if secs > 0
|
945
|
-
Timeout.timeout(secs) do
|
946
|
-
wait(mutex)
|
947
|
-
end
|
948
|
-
else
|
949
|
-
wait(mutex)
|
950
|
-
end
|
951
|
-
end
|
952
|
-
return nil
|
953
|
-
end
|
954
|
-
end
|
955
|
-
|
956
|
-
class IO
|
957
|
-
if defined?(PhusionPassenger::NativeSupport)
|
958
|
-
# Writes all of the strings in the +components+ array into the given file
|
959
|
-
# descriptor using the +writev()+ system call. Unlike IO#write, this method
|
960
|
-
# does not require one to concatenate all those strings into a single buffer
|
961
|
-
# in order to send the data in a single system call. Thus, #writev is a great
|
962
|
-
# way to perform zero-copy I/O.
|
963
|
-
#
|
964
|
-
# Unlike the raw writev() system call, this method ensures that all given
|
965
|
-
# data is written before returning, by performing multiple writev() calls
|
966
|
-
# and whatever else is necessary.
|
967
|
-
#
|
968
|
-
# io.writev(["hello ", "world", "\n"])
|
969
|
-
def writev(components)
|
970
|
-
return PhusionPassenger::NativeSupport.writev(fileno, components)
|
971
|
-
end
|
972
|
-
|
973
|
-
# Like #writev, but accepts two arrays. The data is written in the given order.
|
974
|
-
#
|
975
|
-
# io.writev2(["hello ", "world", "\n"], ["another ", "message\n"])
|
976
|
-
def writev2(components, components2)
|
977
|
-
return PhusionPassenger::NativeSupport.writev2(fileno,
|
978
|
-
components, components2)
|
979
|
-
end
|
980
|
-
|
981
|
-
# Like #writev, but accepts three arrays. The data is written in the given order.
|
982
|
-
#
|
983
|
-
# io.writev3(["hello ", "world", "\n"],
|
984
|
-
# ["another ", "message\n"],
|
985
|
-
# ["yet ", "another ", "one", "\n"])
|
986
|
-
def writev3(components, components2, components3)
|
987
|
-
return PhusionPassenger::NativeSupport.writev3(fileno,
|
988
|
-
components, components2, components3)
|
989
|
-
end
|
990
|
-
end
|
991
|
-
|
992
|
-
if defined?(Fcntl::F_SETFD)
|
993
|
-
def close_on_exec!
|
994
|
-
fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
|
995
|
-
end
|
996
|
-
else
|
997
|
-
def close_on_exec!
|
998
|
-
end
|
999
|
-
end
|
1000
|
-
end
|
1001
|
-
|
1002
|
-
module Signal
|
1003
|
-
# Like Signal.list, but only returns signals that we can actually trap.
|
1004
|
-
def self.list_trappable
|
1005
|
-
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
|
1006
|
-
case ruby_engine
|
1007
|
-
when "ruby"
|
1008
|
-
result = Signal.list
|
1009
|
-
result.delete("ALRM")
|
1010
|
-
result.delete("VTALRM")
|
1011
|
-
when "jruby"
|
1012
|
-
result = Signal.list
|
1013
|
-
result.delete("QUIT")
|
1014
|
-
result.delete("ILL")
|
1015
|
-
result.delete("FPE")
|
1016
|
-
result.delete("KILL")
|
1017
|
-
result.delete("SEGV")
|
1018
|
-
result.delete("USR1")
|
1019
|
-
else
|
1020
|
-
result = Signal.list
|
1021
|
-
end
|
1022
|
-
|
1023
|
-
# Don't touch SIGCHLD no matter what! On OS X waitpid() will
|
1024
|
-
# malfunction if SIGCHLD doesn't have a correct handler.
|
1025
|
-
result.delete("CLD")
|
1026
|
-
result.delete("CHLD")
|
1027
|
-
|
1028
|
-
# Other stuff that we don't want to trap no matter which
|
1029
|
-
# Ruby engine.
|
1030
|
-
result.delete("STOP")
|
1031
|
-
|
1032
|
-
return result
|
1033
|
-
end
|
1034
|
-
end
|
1035
|
-
|
1036
|
-
module Process
|
1037
|
-
def self.timed_waitpid(pid, max_time)
|
1038
|
-
done = false
|
1039
|
-
start_time = Time.now
|
1040
|
-
while Time.now - start_time < max_time && !done
|
1041
|
-
done = Process.waitpid(pid, Process::WNOHANG)
|
1042
|
-
sleep 0.1 if !done
|
1043
|
-
end
|
1044
|
-
return !!done
|
1045
|
-
rescue Errno::ECHILD
|
1046
|
-
return true
|
1047
|
-
end
|
1048
|
-
end
|
1049
|
-
|
1050
|
-
# MRI's implementations of UNIXSocket#recv_io and UNIXSocket#send_io
|
1051
|
-
# are broken on 64-bit FreeBSD 7, OpenBSD and x86_64/ppc64 OS X. So
|
1052
|
-
# we override them with our own implementation.
|
1053
|
-
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
|
1054
|
-
if ruby_engine == "ruby" && defined?(PhusionPassenger::NativeSupport) && (
|
1055
|
-
RUBY_PLATFORM =~ /freebsd/ ||
|
1056
|
-
RUBY_PLATFORM =~ /openbsd/ ||
|
1057
|
-
(RUBY_PLATFORM =~ /darwin/ && RUBY_PLATFORM !~ /universal/)
|
1058
|
-
)
|
1059
|
-
require 'socket'
|
1060
|
-
UNIXSocket.class_eval do
|
1061
|
-
def recv_io(klass = IO)
|
1062
|
-
return klass.for_fd(PhusionPassenger::NativeSupport.recv_fd(self.fileno))
|
1063
|
-
end
|
1064
|
-
|
1065
|
-
def send_io(io)
|
1066
|
-
PhusionPassenger::NativeSupport.send_fd(self.fileno, io.fileno)
|
1067
|
-
end
|
1068
|
-
end
|
1069
|
-
end
|
1070
|
-
|
1071
|
-
module GC
|
1072
|
-
if !respond_to?(:copy_on_write_friendly?)
|
1073
|
-
# Checks whether the current Ruby interpreter's garbage
|
1074
|
-
# collector is copy-on-write friendly.
|
1075
|
-
def self.copy_on_write_friendly?
|
1076
|
-
return false
|
1077
|
-
end
|
1078
|
-
end
|
1079
|
-
end
|