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,89 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* OXT - OS eXtensions for boosT
|
3
|
-
* Provides important functionality necessary for writing robust server software.
|
4
|
-
*
|
5
|
-
* Copyright (c) 2010 Phusion
|
6
|
-
*
|
7
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
* of this software and associated documentation files (the "Software"), to deal
|
9
|
-
* in the Software without restriction, including without limitation the rights
|
10
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
-
* copies of the Software, and to permit persons to whom the Software is
|
12
|
-
* furnished to do so, subject to the following conditions:
|
13
|
-
*
|
14
|
-
* The above copyright notice and this permission notice shall be included in
|
15
|
-
* all copies or substantial portions of the Software.
|
16
|
-
*
|
17
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
-
* THE SOFTWARE.
|
24
|
-
*/
|
25
|
-
#include "tracable_exception.hpp"
|
26
|
-
#include "backtrace.hpp"
|
27
|
-
|
28
|
-
#ifdef OXT_BACKTRACE_IS_ENABLED
|
29
|
-
|
30
|
-
#include <boost/thread/mutex.hpp>
|
31
|
-
#include "macros.hpp"
|
32
|
-
|
33
|
-
namespace oxt {
|
34
|
-
|
35
|
-
using namespace std;
|
36
|
-
|
37
|
-
tracable_exception::tracable_exception() {
|
38
|
-
vector<trace_point *> *backtrace_list;
|
39
|
-
spin_lock *lock;
|
40
|
-
if (OXT_LIKELY(_get_backtrace_list_and_its_lock(&backtrace_list, &lock))) {
|
41
|
-
spin_lock::scoped_lock l(*lock);
|
42
|
-
vector<trace_point *>::const_iterator it;
|
43
|
-
|
44
|
-
for (it = backtrace_list->begin(); it != backtrace_list->end(); it++) {
|
45
|
-
trace_point *p = new trace_point(
|
46
|
-
(*it)->function,
|
47
|
-
(*it)->source,
|
48
|
-
(*it)->line,
|
49
|
-
true);
|
50
|
-
backtrace_copy.push_back(p);
|
51
|
-
}
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
tracable_exception::tracable_exception(const tracable_exception &other)
|
56
|
-
: std::exception()
|
57
|
-
{
|
58
|
-
list<trace_point *>::const_iterator it;
|
59
|
-
for (it = other.backtrace_copy.begin(); it != other.backtrace_copy.end(); it++) {
|
60
|
-
trace_point *p = new trace_point(
|
61
|
-
(*it)->function,
|
62
|
-
(*it)->source,
|
63
|
-
(*it)->line,
|
64
|
-
true);
|
65
|
-
backtrace_copy.push_back(p);
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
tracable_exception::~tracable_exception() throw() {
|
70
|
-
list<trace_point *>::iterator it;
|
71
|
-
for (it = backtrace_copy.begin(); it != backtrace_copy.end(); it++) {
|
72
|
-
delete *it;
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
string
|
77
|
-
tracable_exception::backtrace() const throw() {
|
78
|
-
return _format_backtrace(&backtrace_copy);
|
79
|
-
}
|
80
|
-
|
81
|
-
const char *
|
82
|
-
tracable_exception::what() const throw() {
|
83
|
-
return "oxt::tracable_exception";
|
84
|
-
}
|
85
|
-
|
86
|
-
} // namespace oxt
|
87
|
-
|
88
|
-
#endif
|
89
|
-
|
@@ -1,106 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# Phusion Passenger - http://www.modrails.com/
|
3
|
-
# Copyright (c) 2010 Phusion
|
4
|
-
#
|
5
|
-
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
-
#
|
7
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
# of this software and associated documentation files (the "Software"), to deal
|
9
|
-
# in the Software without restriction, including without limitation the rights
|
10
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
-
# copies of the Software, and to permit persons to whom the Software is
|
12
|
-
# furnished to do so, subject to the following conditions:
|
13
|
-
#
|
14
|
-
# The above copyright notice and this permission notice shall be included in
|
15
|
-
# all copies or substantial portions of the Software.
|
16
|
-
#
|
17
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
-
# THE SOFTWARE.
|
24
|
-
|
25
|
-
require 'socket'
|
26
|
-
|
27
|
-
SERVER_SOCKET_FD = 3
|
28
|
-
OWNER_SOCKET_FD = 4
|
29
|
-
|
30
|
-
begin
|
31
|
-
STDOUT.sync = true
|
32
|
-
STDERR.sync = true
|
33
|
-
$0 = "Passenger spawn server"
|
34
|
-
if GC.respond_to?(:copy_on_write_friendly=)
|
35
|
-
GC.copy_on_write_friendly = true
|
36
|
-
end
|
37
|
-
|
38
|
-
server_socket = UNIXServer.for_fd(SERVER_SOCKET_FD)
|
39
|
-
owner_socket = UNIXSocket.for_fd(OWNER_SOCKET_FD)
|
40
|
-
begin
|
41
|
-
socket_filename = owner_socket.readline.strip
|
42
|
-
socket_password = owner_socket.readline.strip
|
43
|
-
generation_path = owner_socket.readline.strip
|
44
|
-
logging_agent_address = owner_socket.readline.strip
|
45
|
-
logging_agent_username = owner_socket.readline.strip
|
46
|
-
logging_agent_password_base64 = owner_socket.readline.strip
|
47
|
-
node_name = owner_socket.readline.strip
|
48
|
-
log_level = owner_socket.readline.to_i
|
49
|
-
debug_log_file = owner_socket.readline.strip
|
50
|
-
rescue EOFError
|
51
|
-
exit
|
52
|
-
end
|
53
|
-
|
54
|
-
# Optimization for decreasing startup time. Since Apache starts the spawn
|
55
|
-
# server twice during startup, we don't want to load the Passenger classes
|
56
|
-
# if we don't need them.
|
57
|
-
# We check whether Apache immediately closes the connection. If so,
|
58
|
-
# we exit without loading the rest of Passenger. If Apache doesn't close
|
59
|
-
# the connection within 4 seconds then we continue with loading Passenger,
|
60
|
-
# so that loading doesn't happen during the first spawn.
|
61
|
-
begin
|
62
|
-
ios = select([server_socket, owner_socket], nil, nil, 4)
|
63
|
-
if ios
|
64
|
-
readable = ios[0]
|
65
|
-
if !readable.include?(server_socket) && readable.include?(owner_socket)
|
66
|
-
exit
|
67
|
-
end
|
68
|
-
end
|
69
|
-
rescue Interrupt
|
70
|
-
exit
|
71
|
-
end
|
72
|
-
|
73
|
-
source_root = File.expand_path(File.dirname(__FILE__) + "/..")
|
74
|
-
$LOAD_PATH.unshift("#{source_root}/lib")
|
75
|
-
require 'rubygems' rescue nil
|
76
|
-
require 'phusion_passenger'
|
77
|
-
require 'phusion_passenger/debug_logging'
|
78
|
-
require 'phusion_passenger/utils/tmpdir'
|
79
|
-
require 'phusion_passenger/native_support'
|
80
|
-
if defined?(PhusionPassenger::NativeSupport)
|
81
|
-
PhusionPassenger::NativeSupport.disable_stdio_buffering
|
82
|
-
end
|
83
|
-
PhusionPassenger::DebugLogging.log_level = log_level
|
84
|
-
PhusionPassenger::DebugLogging.log_file = debug_log_file
|
85
|
-
PhusionPassenger::Utils.passenger_tmpdir = generation_path
|
86
|
-
if logging_agent_address.empty?
|
87
|
-
options = {}
|
88
|
-
else
|
89
|
-
options = {
|
90
|
-
"logging_agent_address" => logging_agent_address,
|
91
|
-
"logging_agent_username" => logging_agent_username,
|
92
|
-
"logging_agent_password_base64" => logging_agent_password_base64,
|
93
|
-
"node_name" => node_name
|
94
|
-
}
|
95
|
-
end
|
96
|
-
|
97
|
-
require 'phusion_passenger/spawn_manager'
|
98
|
-
spawn_manager = PhusionPassenger::SpawnManager.new(options)
|
99
|
-
spawn_manager.start_synchronously(socket_filename, socket_password, server_socket, owner_socket)
|
100
|
-
spawn_manager.cleanup
|
101
|
-
rescue => e
|
102
|
-
require 'phusion_passenger/utils'
|
103
|
-
include PhusionPassenger::Utils
|
104
|
-
print_exception("spawn manager", e)
|
105
|
-
exit 10
|
106
|
-
end
|
@@ -1,766 +0,0 @@
|
|
1
|
-
# encoding: binary
|
2
|
-
# Phusion Passenger - http://www.modrails.com/
|
3
|
-
# Copyright (c) 2010 Phusion
|
4
|
-
#
|
5
|
-
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
|
-
#
|
7
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
# of this software and associated documentation files (the "Software"), to deal
|
9
|
-
# in the Software without restriction, including without limitation the rights
|
10
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
-
# copies of the Software, and to permit persons to whom the Software is
|
12
|
-
# furnished to do so, subject to the following conditions:
|
13
|
-
#
|
14
|
-
# The above copyright notice and this permission notice shall be included in
|
15
|
-
# all copies or substantial portions of the Software.
|
16
|
-
#
|
17
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
-
# THE SOFTWARE.
|
24
|
-
|
25
|
-
require 'socket'
|
26
|
-
require 'fcntl'
|
27
|
-
require 'phusion_passenger'
|
28
|
-
require 'phusion_passenger/constants'
|
29
|
-
require 'phusion_passenger/public_api'
|
30
|
-
require 'phusion_passenger/message_channel'
|
31
|
-
require 'phusion_passenger/message_client'
|
32
|
-
require 'phusion_passenger/debug_logging'
|
33
|
-
require 'phusion_passenger/utils'
|
34
|
-
require 'phusion_passenger/utils/tmpdir'
|
35
|
-
require 'phusion_passenger/utils/unseekable_socket'
|
36
|
-
require 'phusion_passenger/native_support'
|
37
|
-
|
38
|
-
module PhusionPassenger
|
39
|
-
|
40
|
-
# The request handler is the layer which connects Apache with the underlying application's
|
41
|
-
# request dispatcher (i.e. either Rails's Dispatcher class or Rack).
|
42
|
-
# The request handler's job is to process incoming HTTP requests using the
|
43
|
-
# currently loaded Ruby on Rails application. HTTP requests are forwarded
|
44
|
-
# to the request handler by the web server. HTTP responses generated by the
|
45
|
-
# RoR application are forwarded to the web server, which, in turn, sends the
|
46
|
-
# response back to the HTTP client.
|
47
|
-
#
|
48
|
-
# AbstractRequestHandler is an abstract base class for easing the implementation
|
49
|
-
# of request handlers for Rails and Rack.
|
50
|
-
#
|
51
|
-
# == Design decisions
|
52
|
-
#
|
53
|
-
# Some design decisions are made because we want to decrease system
|
54
|
-
# administrator maintenance overhead. These decisions are documented
|
55
|
-
# in this section.
|
56
|
-
#
|
57
|
-
# === Owner pipes
|
58
|
-
#
|
59
|
-
# Because only the web server communicates directly with a request handler,
|
60
|
-
# we want the request handler to exit if the web server has also exited.
|
61
|
-
# This is implemented by using a so-called _owner pipe_. The writable part
|
62
|
-
# of the pipe will be passed to the web server* via a Unix socket, and the web
|
63
|
-
# server will own that part of the pipe, while AbstractRequestHandler owns
|
64
|
-
# the readable part of the pipe. AbstractRequestHandler will continuously
|
65
|
-
# check whether the other side of the pipe has been closed. If so, then it
|
66
|
-
# knows that the web server has exited, and so the request handler will exit
|
67
|
-
# as well. This works even if the web server gets killed by SIGKILL.
|
68
|
-
#
|
69
|
-
# * It might also be passed to the ApplicationPoolServerExecutable, if the web
|
70
|
-
# server's using ApplicationPoolServer instead of StandardApplicationPool.
|
71
|
-
#
|
72
|
-
#
|
73
|
-
# == Request format
|
74
|
-
#
|
75
|
-
# Incoming "HTTP requests" are not true HTTP requests, i.e. their binary
|
76
|
-
# representation do not conform to RFC 2616. Instead, the request format
|
77
|
-
# is based on CGI, and is similar to that of SCGI.
|
78
|
-
#
|
79
|
-
# The format consists of 3 parts:
|
80
|
-
# - A 32-bit big-endian integer, containing the size of the transformed
|
81
|
-
# headers.
|
82
|
-
# - The transformed HTTP headers.
|
83
|
-
# - The verbatim (untransformed) HTTP request body.
|
84
|
-
#
|
85
|
-
# HTTP headers are transformed to a format that satisfies the following
|
86
|
-
# grammar:
|
87
|
-
#
|
88
|
-
# headers ::= header*
|
89
|
-
# header ::= name NUL value NUL
|
90
|
-
# name ::= notnull+
|
91
|
-
# value ::= notnull+
|
92
|
-
# notnull ::= "\x01" | "\x02" | "\x02" | ... | "\xFF"
|
93
|
-
# NUL = "\x00"
|
94
|
-
#
|
95
|
-
# The web server transforms the HTTP request to the aforementioned format,
|
96
|
-
# and sends it to the request handler.
|
97
|
-
class AbstractRequestHandler
|
98
|
-
include DebugLogging
|
99
|
-
|
100
|
-
# Signal which will cause the Rails application to exit immediately.
|
101
|
-
HARD_TERMINATION_SIGNAL = "SIGTERM"
|
102
|
-
# Signal which will cause the Rails application to exit as soon as it's done processing a request.
|
103
|
-
SOFT_TERMINATION_SIGNAL = "SIGUSR1"
|
104
|
-
BACKLOG_SIZE = 500
|
105
|
-
MAX_HEADER_SIZE = 128 * 1024
|
106
|
-
|
107
|
-
# String constants which exist to relieve Ruby's garbage collector.
|
108
|
-
IGNORE = 'IGNORE' # :nodoc:
|
109
|
-
DEFAULT = 'DEFAULT' # :nodoc:
|
110
|
-
X_POWERED_BY = 'X-Powered-By' # :nodoc:
|
111
|
-
REQUEST_METHOD = 'REQUEST_METHOD' # :nodoc:
|
112
|
-
PING = 'PING' # :nodoc:
|
113
|
-
PASSENGER_CONNECT_PASSWORD = "PASSENGER_CONNECT_PASSWORD" # :nodoc:
|
114
|
-
|
115
|
-
OBJECT_SPACE_SUPPORTS_LIVE_OBJECTS = ObjectSpace.respond_to?(:live_objects)
|
116
|
-
OBJECT_SPACE_SUPPORTS_ALLOCATED_OBJECTS = ObjectSpace.respond_to?(:allocated_objects)
|
117
|
-
OBJECT_SPACE_SUPPORTS_COUNT_OBJECTS = ObjectSpace.respond_to?(:count_objects)
|
118
|
-
GC_SUPPORTS_TIME = GC.respond_to?(:time)
|
119
|
-
GC_SUPPORTS_CLEAR_STATS = GC.respond_to?(:clear_stats)
|
120
|
-
|
121
|
-
# A hash containing all server sockets that this request handler listens on.
|
122
|
-
# The hash is in the form of:
|
123
|
-
#
|
124
|
-
# {
|
125
|
-
# name1 => [socket_address1, socket_type1, socket1],
|
126
|
-
# name2 => [socket_address2, socket_type2, socket2],
|
127
|
-
# ...
|
128
|
-
# }
|
129
|
-
#
|
130
|
-
# +name+ is a Symbol. +socket_addressx+ is the address of the socket,
|
131
|
-
# +socket_typex+ is the socket's type (either 'unix' or 'tcp') and
|
132
|
-
# +socketx+ is the actual socket IO objec.
|
133
|
-
# There's guaranteed to be at least one server socket, namely one with the
|
134
|
-
# name +:main+.
|
135
|
-
attr_reader :server_sockets
|
136
|
-
|
137
|
-
# Specifies the maximum allowed memory usage, in MB. If after having processed
|
138
|
-
# a request AbstractRequestHandler detects that memory usage has risen above
|
139
|
-
# this limit, then it will gracefully exit (that is, exit after having processed
|
140
|
-
# all pending requests).
|
141
|
-
#
|
142
|
-
# A value of 0 (the default) indicates that there's no limit.
|
143
|
-
attr_accessor :memory_limit
|
144
|
-
|
145
|
-
# The number of times the main loop has iterated so far. Mostly useful
|
146
|
-
# for unit test assertions.
|
147
|
-
attr_reader :iterations
|
148
|
-
|
149
|
-
# Number of requests processed so far. This includes requests that raised
|
150
|
-
# exceptions.
|
151
|
-
attr_reader :processed_requests
|
152
|
-
|
153
|
-
# If a soft termination signal was received, then the main loop will quit
|
154
|
-
# the given amount of seconds after the last time a connection was accepted.
|
155
|
-
# Defaults to 3 seconds.
|
156
|
-
attr_accessor :soft_termination_linger_time
|
157
|
-
|
158
|
-
# A password with which clients must authenticate. Default is unauthenticated.
|
159
|
-
attr_accessor :connect_password
|
160
|
-
|
161
|
-
# Create a new RequestHandler with the given owner pipe.
|
162
|
-
# +owner_pipe+ must be the readable part of a pipe IO object.
|
163
|
-
#
|
164
|
-
# Additionally, the following options may be given:
|
165
|
-
# - memory_limit: Used to set the +memory_limit+ attribute.
|
166
|
-
# - detach_key
|
167
|
-
# - connect_password
|
168
|
-
# - pool_account_username
|
169
|
-
# - pool_account_password_base64
|
170
|
-
def initialize(owner_pipe, options = {})
|
171
|
-
@server_sockets = {}
|
172
|
-
|
173
|
-
if should_use_unix_sockets?
|
174
|
-
@main_socket_address, @main_socket = create_unix_socket_on_filesystem
|
175
|
-
@server_sockets[:main] = [@main_socket_address, 'unix', @main_socket]
|
176
|
-
else
|
177
|
-
@main_socket_address, @main_socket = create_tcp_socket
|
178
|
-
@server_sockets[:main] = [@main_socket_address, 'tcp', @main_socket]
|
179
|
-
end
|
180
|
-
|
181
|
-
@http_socket_address, @http_socket = create_tcp_socket
|
182
|
-
@server_sockets[:http] = [@http_socket_address, 'tcp', @http_socket]
|
183
|
-
|
184
|
-
@owner_pipe = owner_pipe
|
185
|
-
@options = options
|
186
|
-
@previous_signal_handlers = {}
|
187
|
-
@main_loop_generation = 0
|
188
|
-
@main_loop_thread_lock = Mutex.new
|
189
|
-
@main_loop_thread_cond = ConditionVariable.new
|
190
|
-
@memory_limit = options["memory_limit"] || 0
|
191
|
-
@connect_password = options["connect_password"]
|
192
|
-
@detach_key = options["detach_key"]
|
193
|
-
@pool_account_username = options["pool_account_username"]
|
194
|
-
if options["pool_account_password_base64"]
|
195
|
-
@pool_account_password = options["pool_account_password_base64"].unpack('m').first
|
196
|
-
end
|
197
|
-
@analytics_logger = options["analytics_logger"]
|
198
|
-
@iterations = 0
|
199
|
-
@processed_requests = 0
|
200
|
-
@soft_termination_linger_time = 3
|
201
|
-
@main_loop_running = false
|
202
|
-
@passenger_header = determine_passenger_header
|
203
|
-
|
204
|
-
@debugger = @options["debugger"]
|
205
|
-
if @debugger
|
206
|
-
@server_sockets[:ruby_debug_cmd] = ["127.0.0.1:#{Debugger.cmd_port}", 'tcp']
|
207
|
-
@server_sockets[:ruby_debug_ctrl] = ["127.0.0.1:#{Debugger.ctrl_port}", 'tcp']
|
208
|
-
end
|
209
|
-
|
210
|
-
#############
|
211
|
-
end
|
212
|
-
|
213
|
-
# Clean up temporary stuff created by the request handler.
|
214
|
-
#
|
215
|
-
# If the main loop was started by #main_loop, then this method may only
|
216
|
-
# be called after the main loop has exited.
|
217
|
-
#
|
218
|
-
# If the main loop was started by #start_main_loop_thread, then this method
|
219
|
-
# may be called at any time, and it will stop the main loop thread.
|
220
|
-
def cleanup
|
221
|
-
if @main_loop_thread
|
222
|
-
@main_loop_thread_lock.synchronize do
|
223
|
-
@graceful_termination_pipe[1].close rescue nil
|
224
|
-
end
|
225
|
-
@main_loop_thread.join
|
226
|
-
end
|
227
|
-
@server_sockets.each_value do |value|
|
228
|
-
address, type, socket = value
|
229
|
-
socket.close rescue nil
|
230
|
-
if type == 'unix'
|
231
|
-
File.unlink(address) rescue nil
|
232
|
-
end
|
233
|
-
end
|
234
|
-
@owner_pipe.close rescue nil
|
235
|
-
end
|
236
|
-
|
237
|
-
# Check whether the main loop's currently running.
|
238
|
-
def main_loop_running?
|
239
|
-
return @main_loop_running
|
240
|
-
end
|
241
|
-
|
242
|
-
# Enter the request handler's main loop.
|
243
|
-
def main_loop
|
244
|
-
debug("Entering request handler main loop")
|
245
|
-
reset_signal_handlers
|
246
|
-
begin
|
247
|
-
@graceful_termination_pipe = IO.pipe
|
248
|
-
@graceful_termination_pipe[0].close_on_exec!
|
249
|
-
@graceful_termination_pipe[1].close_on_exec!
|
250
|
-
|
251
|
-
@main_loop_thread_lock.synchronize do
|
252
|
-
@main_loop_generation += 1
|
253
|
-
@main_loop_running = true
|
254
|
-
@main_loop_thread_cond.broadcast
|
255
|
-
|
256
|
-
@select_timeout = nil
|
257
|
-
|
258
|
-
@selectable_sockets = []
|
259
|
-
@server_sockets.each_value do |value|
|
260
|
-
socket = value[2]
|
261
|
-
@selectable_sockets << socket if socket
|
262
|
-
end
|
263
|
-
@selectable_sockets << @owner_pipe
|
264
|
-
@selectable_sockets << @graceful_termination_pipe[0]
|
265
|
-
end
|
266
|
-
|
267
|
-
install_useful_signal_handlers
|
268
|
-
socket_wrapper = Utils::UnseekableSocket.new
|
269
|
-
channel = MessageChannel.new
|
270
|
-
buffer = ''
|
271
|
-
|
272
|
-
while true
|
273
|
-
@iterations += 1
|
274
|
-
if !accept_and_process_next_request(socket_wrapper, channel, buffer)
|
275
|
-
trace(2, "Request handler main loop exited normally")
|
276
|
-
break
|
277
|
-
end
|
278
|
-
@processed_requests += 1
|
279
|
-
end
|
280
|
-
rescue EOFError
|
281
|
-
# Exit main loop.
|
282
|
-
trace(2, "Request handler main loop interrupted by EOFError exception")
|
283
|
-
rescue Interrupt
|
284
|
-
# Exit main loop.
|
285
|
-
trace(2, "Request handler main loop interrupted by Interrupt exception")
|
286
|
-
rescue SignalException => signal
|
287
|
-
trace(2, "Request handler main loop interrupted by SignalException")
|
288
|
-
if signal.message != HARD_TERMINATION_SIGNAL &&
|
289
|
-
signal.message != SOFT_TERMINATION_SIGNAL
|
290
|
-
raise
|
291
|
-
end
|
292
|
-
rescue Exception => e
|
293
|
-
trace(2, "Request handler main loop interrupted by #{e.class} exception")
|
294
|
-
raise
|
295
|
-
ensure
|
296
|
-
debug("Exiting request handler main loop")
|
297
|
-
revert_signal_handlers
|
298
|
-
@main_loop_thread_lock.synchronize do
|
299
|
-
@graceful_termination_pipe[1].close rescue nil
|
300
|
-
@graceful_termination_pipe[0].close rescue nil
|
301
|
-
@selectable_sockets = []
|
302
|
-
@main_loop_generation += 1
|
303
|
-
@main_loop_running = false
|
304
|
-
@main_loop_thread_cond.broadcast
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
# Start the main loop in a new thread. This thread will be stopped by #cleanup.
|
310
|
-
def start_main_loop_thread
|
311
|
-
current_generation = @main_loop_generation
|
312
|
-
@main_loop_thread = Thread.new do
|
313
|
-
begin
|
314
|
-
main_loop
|
315
|
-
rescue Exception => e
|
316
|
-
print_exception(self.class, e)
|
317
|
-
end
|
318
|
-
end
|
319
|
-
@main_loop_thread_lock.synchronize do
|
320
|
-
while @main_loop_generation == current_generation
|
321
|
-
@main_loop_thread_cond.wait(@main_loop_thread_lock)
|
322
|
-
end
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
# Remove this request handler from the application pool so that no
|
327
|
-
# new connections will come in. Then make the main loop quit a few
|
328
|
-
# seconds after the last time a connection came in. This all is to
|
329
|
-
# ensure that no connections come in while we're shutting down.
|
330
|
-
#
|
331
|
-
# May only be called while the main loop is running. May be called
|
332
|
-
# from any thread.
|
333
|
-
def soft_shutdown
|
334
|
-
unless @soft_terminated
|
335
|
-
@soft_terminated = true
|
336
|
-
@select_timeout = @soft_termination_linger_time
|
337
|
-
@graceful_termination_pipe[1].close rescue nil
|
338
|
-
if @detach_key && @pool_account_username && @pool_account_password
|
339
|
-
client = MessageClient.new(@pool_account_username, @pool_account_password)
|
340
|
-
begin
|
341
|
-
client.detach(@detach_key)
|
342
|
-
ensure
|
343
|
-
client.close
|
344
|
-
end
|
345
|
-
end
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
private
|
350
|
-
include Utils
|
351
|
-
|
352
|
-
def should_use_unix_sockets?
|
353
|
-
# Historical note:
|
354
|
-
# There seems to be a bug in MacOS X Leopard w.r.t. Unix server
|
355
|
-
# sockets file descriptors that are passed to another process.
|
356
|
-
# Usually Unix server sockets work fine, but when they're passed
|
357
|
-
# to another process, then clients that connect to the socket
|
358
|
-
# can incorrectly determine that the client socket is closed,
|
359
|
-
# even though that's not actually the case. More specifically:
|
360
|
-
# recv()/read() calls on these client sockets can return 0 even
|
361
|
-
# when we know EOF is not reached.
|
362
|
-
#
|
363
|
-
# The ApplicationPool infrastructure used to connect to a backend
|
364
|
-
# process's Unix socket in the helper server process, and then
|
365
|
-
# pass the connection file descriptor to the web server, which
|
366
|
-
# triggers this kernel bug. We used to work around this by using
|
367
|
-
# TCP sockets instead of Unix sockets; TCP sockets can still fail
|
368
|
-
# with this fake-EOF bug once in a while, but not nearly as often
|
369
|
-
# as with Unix sockets.
|
370
|
-
#
|
371
|
-
# This problem no longer applies today. The client socket is now
|
372
|
-
# created directly in the web server, and the bug is no longer
|
373
|
-
# triggered. Nevertheless, we keep this function intact so that
|
374
|
-
# if something like this ever happens again, we know why, and we
|
375
|
-
# can easily reactivate the workaround. Or maybe if we just need
|
376
|
-
# TCP sockets for some other reason.
|
377
|
-
|
378
|
-
#return RUBY_PLATFORM !~ /darwin/
|
379
|
-
return true
|
380
|
-
end
|
381
|
-
|
382
|
-
def create_unix_socket_on_filesystem
|
383
|
-
while true
|
384
|
-
begin
|
385
|
-
if defined?(NativeSupport)
|
386
|
-
unix_path_max = NativeSupport::UNIX_PATH_MAX
|
387
|
-
else
|
388
|
-
unix_path_max = 100
|
389
|
-
end
|
390
|
-
socket_address = "#{passenger_tmpdir}/backends/ruby.#{generate_random_id(:base64)}"
|
391
|
-
socket_address = socket_address.slice(0, unix_path_max - 1)
|
392
|
-
socket = UNIXServer.new(socket_address)
|
393
|
-
socket.listen(BACKLOG_SIZE)
|
394
|
-
socket.close_on_exec!
|
395
|
-
File.chmod(0666, socket_address)
|
396
|
-
return [socket_address, socket]
|
397
|
-
rescue Errno::EADDRINUSE
|
398
|
-
# Do nothing, try again with another name.
|
399
|
-
end
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
def create_tcp_socket
|
404
|
-
# We use "127.0.0.1" as address in order to force
|
405
|
-
# TCPv4 instead of TCPv6.
|
406
|
-
socket = TCPServer.new('127.0.0.1', 0)
|
407
|
-
socket.listen(BACKLOG_SIZE)
|
408
|
-
socket.close_on_exec!
|
409
|
-
socket_address = "127.0.0.1:#{socket.addr[1]}"
|
410
|
-
return [socket_address, socket]
|
411
|
-
end
|
412
|
-
|
413
|
-
# Reset signal handlers to their default handler, and install some
|
414
|
-
# special handlers for a few signals. The previous signal handlers
|
415
|
-
# will be put back by calling revert_signal_handlers.
|
416
|
-
def reset_signal_handlers
|
417
|
-
Signal.list_trappable.each_key do |signal|
|
418
|
-
begin
|
419
|
-
prev_handler = trap(signal, DEFAULT)
|
420
|
-
if prev_handler != DEFAULT
|
421
|
-
@previous_signal_handlers[signal] = prev_handler
|
422
|
-
end
|
423
|
-
rescue ArgumentError
|
424
|
-
# Signal cannot be trapped; ignore it.
|
425
|
-
end
|
426
|
-
end
|
427
|
-
trap('HUP', IGNORE)
|
428
|
-
PhusionPassenger.call_event(:after_installing_signal_handlers)
|
429
|
-
end
|
430
|
-
|
431
|
-
def install_useful_signal_handlers
|
432
|
-
trappable_signals = Signal.list_trappable
|
433
|
-
|
434
|
-
trap(SOFT_TERMINATION_SIGNAL) do
|
435
|
-
begin
|
436
|
-
soft_shutdown
|
437
|
-
rescue => e
|
438
|
-
print_exception("Passenger RequestHandler soft shutdown routine", e)
|
439
|
-
end
|
440
|
-
end if trappable_signals.has_key?(SOFT_TERMINATION_SIGNAL.sub(/^SIG/, ''))
|
441
|
-
|
442
|
-
trap('ABRT') do
|
443
|
-
raise SignalException, "SIGABRT"
|
444
|
-
end if trappable_signals.has_key?('ABRT')
|
445
|
-
|
446
|
-
trap('QUIT') do
|
447
|
-
warn(global_backtrace_report)
|
448
|
-
end if trappable_signals.has_key?('QUIT')
|
449
|
-
end
|
450
|
-
|
451
|
-
def revert_signal_handlers
|
452
|
-
@previous_signal_handlers.each_pair do |signal, handler|
|
453
|
-
trap(signal, handler)
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
class IgnoreException < StandardError
|
458
|
-
end
|
459
|
-
|
460
|
-
def accept_and_process_next_request(socket_wrapper, channel, buffer)
|
461
|
-
select_result = select(@selectable_sockets, nil, nil, @select_timeout)
|
462
|
-
if select_result.nil?
|
463
|
-
# This can only happen after we've received a soft termination
|
464
|
-
# signal. No connection was accepted for @select_timeout seconds,
|
465
|
-
# so now we quit the main loop.
|
466
|
-
trace(2, "Soft termination timeout")
|
467
|
-
return false
|
468
|
-
end
|
469
|
-
|
470
|
-
ios = select_result.first
|
471
|
-
if ios.include?(@main_socket)
|
472
|
-
trace(3, "Accepting new request on main socket")
|
473
|
-
connection = socket_wrapper.wrap(@main_socket.accept)
|
474
|
-
channel.io = connection
|
475
|
-
headers, input_stream = parse_native_request(connection, channel, buffer)
|
476
|
-
full_http_response = false
|
477
|
-
elsif ios.include?(@http_socket)
|
478
|
-
trace(3, "Accepting new request on HTTP socket")
|
479
|
-
connection = socket_wrapper.wrap(@http_socket.accept)
|
480
|
-
headers, input_stream = parse_http_request(connection)
|
481
|
-
full_http_response = true
|
482
|
-
else
|
483
|
-
# The other end of the owner pipe has been closed, or the
|
484
|
-
# graceful termination pipe has been closed. This is our
|
485
|
-
# call to gracefully terminate (after having processed all
|
486
|
-
# incoming requests).
|
487
|
-
if @select_timeout
|
488
|
-
# But if @select_timeout is set then it means that we
|
489
|
-
# received a soft termination signal. In that case
|
490
|
-
# we don't want to quit immediately, but @select_timeout
|
491
|
-
# seconds after the last time a connection was accepted.
|
492
|
-
#
|
493
|
-
# #soft_shutdown not only closes the graceful termination
|
494
|
-
# pipe, but it also tells the application pool to remove
|
495
|
-
# this process from the pool, which will cause the owner
|
496
|
-
# pipe to be closed. So we remove both IO objects
|
497
|
-
# from @selectable_sockets in order to prevent the
|
498
|
-
# next select call from immediately returning, allowing
|
499
|
-
# it to time out.
|
500
|
-
@selectable_sockets.delete(@graceful_termination_pipe[0])
|
501
|
-
@selectable_sockets.delete(@owner_pipe)
|
502
|
-
return true
|
503
|
-
else
|
504
|
-
if ios.include?(@owner_pipe)
|
505
|
-
trace(2, "Owner pipe closed")
|
506
|
-
elsif ios.include?(@graceful_termination_pipe[0])
|
507
|
-
trace(2, "Graceful termination pipe closed")
|
508
|
-
end
|
509
|
-
return false
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
if headers
|
514
|
-
prepare_request(headers)
|
515
|
-
ignore = false
|
516
|
-
begin
|
517
|
-
if headers[REQUEST_METHOD] == PING
|
518
|
-
process_ping(headers, input_stream, connection)
|
519
|
-
else
|
520
|
-
process_request(headers, input_stream, connection, full_http_response)
|
521
|
-
end
|
522
|
-
rescue IgnoreException
|
523
|
-
ignore = true
|
524
|
-
rescue Exception
|
525
|
-
has_error = true
|
526
|
-
raise
|
527
|
-
ensure
|
528
|
-
finalize_request(headers, has_error) if !ignore
|
529
|
-
end
|
530
|
-
end
|
531
|
-
return true
|
532
|
-
rescue => e
|
533
|
-
if socket_wrapper.source_of_exception?(e)
|
534
|
-
# EPIPE is harmless, it just means that the client closed the connection.
|
535
|
-
# Other errors might indicate a problem so we print them, but they're
|
536
|
-
# probably not bad enough to warrant stopping the request handler.
|
537
|
-
if !e.is_a?(Errno::EPIPE)
|
538
|
-
print_exception("Passenger RequestHandler's client socket", e)
|
539
|
-
end
|
540
|
-
return true
|
541
|
-
else
|
542
|
-
if @analytics_logger && headers && headers[PASSENGER_TXN_ID]
|
543
|
-
log_analytics_exception(headers, e)
|
544
|
-
end
|
545
|
-
raise e
|
546
|
-
end
|
547
|
-
ensure
|
548
|
-
# The 'close_write' here prevents forked child
|
549
|
-
# processes from unintentionally keeping the
|
550
|
-
# connection open.
|
551
|
-
if connection && !connection.closed?
|
552
|
-
begin
|
553
|
-
connection.close_write
|
554
|
-
rescue SystemCallError
|
555
|
-
end
|
556
|
-
begin
|
557
|
-
connection.close
|
558
|
-
rescue SystemCallError
|
559
|
-
end
|
560
|
-
end
|
561
|
-
if input_stream && !input_stream.closed?
|
562
|
-
input_stream.close rescue nil
|
563
|
-
end
|
564
|
-
end
|
565
|
-
|
566
|
-
# Read the next request from the given socket, and return
|
567
|
-
# a pair [headers, input_stream]. _headers_ is a Hash containing
|
568
|
-
# the request headers, while _input_stream_ is an IO object for
|
569
|
-
# reading HTTP POST data.
|
570
|
-
#
|
571
|
-
# Returns nil if end-of-stream was encountered.
|
572
|
-
def parse_native_request(socket, channel, buffer)
|
573
|
-
headers_data = channel.read_scalar(buffer, MAX_HEADER_SIZE)
|
574
|
-
if headers_data.nil?
|
575
|
-
return
|
576
|
-
end
|
577
|
-
headers = split_by_null_into_hash(headers_data)
|
578
|
-
if @connect_password && headers[PASSENGER_CONNECT_PASSWORD] != @connect_password
|
579
|
-
warn "*** Passenger RequestHandler warning: " <<
|
580
|
-
"someone tried to connect with an invalid connect password."
|
581
|
-
return
|
582
|
-
else
|
583
|
-
return [headers, socket]
|
584
|
-
end
|
585
|
-
rescue SecurityError => e
|
586
|
-
warn("*** Passenger RequestHandler warning: " <<
|
587
|
-
"HTTP header size exceeded maximum.")
|
588
|
-
return nil
|
589
|
-
end
|
590
|
-
|
591
|
-
# Like parse_native_request, but parses an HTTP request. This is a very minimalistic
|
592
|
-
# HTTP parser and is not intended to be complete, fast or secure, since the HTTP server
|
593
|
-
# socket is intended to be used for debugging purposes only.
|
594
|
-
def parse_http_request(socket)
|
595
|
-
headers = {}
|
596
|
-
|
597
|
-
data = ""
|
598
|
-
while data !~ /\r\n\r\n/ && data.size < MAX_HEADER_SIZE
|
599
|
-
data << socket.readpartial(16 * 1024)
|
600
|
-
end
|
601
|
-
if data.size >= MAX_HEADER_SIZE
|
602
|
-
warn("*** Passenger RequestHandler warning: " <<
|
603
|
-
"HTTP header size exceeded maximum.")
|
604
|
-
return nil
|
605
|
-
end
|
606
|
-
|
607
|
-
data.gsub!(/\r\n\r\n.*/, '')
|
608
|
-
data.split("\r\n").each_with_index do |line, i|
|
609
|
-
if i == 0
|
610
|
-
# GET / HTTP/1.1
|
611
|
-
line =~ /^([A-Za-z]+) (.+?) (HTTP\/\d\.\d)$/
|
612
|
-
request_method = $1
|
613
|
-
request_uri = $2
|
614
|
-
protocol = $3
|
615
|
-
path_info, query_string = request_uri.split("?", 2)
|
616
|
-
headers[REQUEST_METHOD] = request_method
|
617
|
-
headers["REQUEST_URI"] = request_uri
|
618
|
-
headers["QUERY_STRING"] = query_string || ""
|
619
|
-
headers["SCRIPT_NAME"] = ""
|
620
|
-
headers["PATH_INFO"] = path_info
|
621
|
-
headers["SERVER_NAME"] = "127.0.0.1"
|
622
|
-
headers["SERVER_PORT"] = socket.addr[1].to_s
|
623
|
-
headers["SERVER_PROTOCOL"] = protocol
|
624
|
-
else
|
625
|
-
header, value = line.split(/\s*:\s*/, 2)
|
626
|
-
header.upcase! # "Foo-Bar" => "FOO-BAR"
|
627
|
-
header.gsub!("-", "_") # => "FOO_BAR"
|
628
|
-
if header == "CONTENT_LENGTH" || header == "CONTENT_TYPE"
|
629
|
-
headers[header] = value
|
630
|
-
else
|
631
|
-
headers["HTTP_#{header}"] = value
|
632
|
-
end
|
633
|
-
end
|
634
|
-
end
|
635
|
-
|
636
|
-
if @connect_password && headers["HTTP_X_PASSENGER_CONNECT_PASSWORD"] != @connect_password
|
637
|
-
warn "*** Passenger RequestHandler warning: " <<
|
638
|
-
"someone tried to connect with an invalid connect password."
|
639
|
-
return
|
640
|
-
else
|
641
|
-
return [headers, socket]
|
642
|
-
end
|
643
|
-
rescue EOFError
|
644
|
-
return nil
|
645
|
-
end
|
646
|
-
|
647
|
-
def process_ping(env, input, output)
|
648
|
-
output.write("pong")
|
649
|
-
end
|
650
|
-
|
651
|
-
def determine_passenger_header
|
652
|
-
header = "Phusion Passenger (mod_rails/mod_rack)"
|
653
|
-
if @options["show_version_in_header"]
|
654
|
-
header << " #{VERSION_STRING}"
|
655
|
-
end
|
656
|
-
if File.exist?("#{SOURCE_ROOT}/enterprisey.txt") ||
|
657
|
-
File.exist?("/etc/passenger_enterprisey.txt")
|
658
|
-
header << ", Enterprise Edition"
|
659
|
-
end
|
660
|
-
return header
|
661
|
-
end
|
662
|
-
|
663
|
-
def prepare_request(headers)
|
664
|
-
if @analytics_logger && headers[PASSENGER_TXN_ID]
|
665
|
-
txn_id = headers[PASSENGER_TXN_ID]
|
666
|
-
group_name = headers[PASSENGER_GROUP_NAME]
|
667
|
-
union_station_key = headers[PASSENGER_UNION_STATION_KEY]
|
668
|
-
log = @analytics_logger.continue_transaction(txn_id, group_name,
|
669
|
-
:requests, union_station_key)
|
670
|
-
headers[PASSENGER_ANALYTICS_WEB_LOG] = log
|
671
|
-
Thread.current[PASSENGER_ANALYTICS_WEB_LOG] = log
|
672
|
-
Thread.current[PASSENGER_TXN_ID] = txn_id
|
673
|
-
Thread.current[PASSENGER_GROUP_NAME] = group_name
|
674
|
-
Thread.current[PASSENGER_UNION_STATION_KEY] = union_station_key
|
675
|
-
if OBJECT_SPACE_SUPPORTS_LIVE_OBJECTS
|
676
|
-
log.message("Initial objects on heap: #{ObjectSpace.live_objects}")
|
677
|
-
end
|
678
|
-
if OBJECT_SPACE_SUPPORTS_ALLOCATED_OBJECTS
|
679
|
-
log.message("Initial objects allocated so far: #{ObjectSpace.allocated_objects}")
|
680
|
-
elsif OBJECT_SPACE_SUPPORTS_COUNT_OBJECTS
|
681
|
-
count = ObjectSpace.count_objects
|
682
|
-
log.message("Initial objects allocated so far: #{count[:TOTAL] - count[:FREE]}")
|
683
|
-
end
|
684
|
-
if GC_SUPPORTS_TIME
|
685
|
-
log.message("Initial GC time: #{GC.time}")
|
686
|
-
end
|
687
|
-
log.begin_measure("app request handler processing")
|
688
|
-
end
|
689
|
-
|
690
|
-
#################
|
691
|
-
end
|
692
|
-
|
693
|
-
def finalize_request(headers, has_error)
|
694
|
-
log = headers[PASSENGER_ANALYTICS_WEB_LOG]
|
695
|
-
if log && !log.closed?
|
696
|
-
exception_occurred = false
|
697
|
-
begin
|
698
|
-
log.end_measure("app request handler processing", has_error)
|
699
|
-
if OBJECT_SPACE_SUPPORTS_LIVE_OBJECTS
|
700
|
-
log.message("Final objects on heap: #{ObjectSpace.live_objects}")
|
701
|
-
end
|
702
|
-
if OBJECT_SPACE_SUPPORTS_ALLOCATED_OBJECTS
|
703
|
-
log.message("Final objects allocated so far: #{ObjectSpace.allocated_objects}")
|
704
|
-
elsif OBJECT_SPACE_SUPPORTS_COUNT_OBJECTS
|
705
|
-
count = ObjectSpace.count_objects
|
706
|
-
log.message("Final objects allocated so far: #{count[:TOTAL] - count[:FREE]}")
|
707
|
-
end
|
708
|
-
if GC_SUPPORTS_TIME
|
709
|
-
log.message("Final GC time: #{GC.time}")
|
710
|
-
end
|
711
|
-
if GC_SUPPORTS_CLEAR_STATS
|
712
|
-
# Clear statistics to void integer wraps.
|
713
|
-
GC.clear_stats
|
714
|
-
end
|
715
|
-
Thread.current[PASSENGER_ANALYTICS_WEB_LOG] = nil
|
716
|
-
rescue Exception
|
717
|
-
# Maybe this exception was raised while communicating
|
718
|
-
# with the logging agent. If that is the case then
|
719
|
-
# log.close may also raise an exception, but we're only
|
720
|
-
# interested in the original exception. So if this
|
721
|
-
# situation occurs we must ignore any exceptions raised
|
722
|
-
# by log.close.
|
723
|
-
exception_occurred = true
|
724
|
-
raise
|
725
|
-
ensure
|
726
|
-
# It is important that the following call receives an ACK
|
727
|
-
# from the logging agent and that we don't close the socket
|
728
|
-
# connection until the ACK has been received, otherwise
|
729
|
-
# the helper agent may close the transaction before this
|
730
|
-
# process's openTransaction command is processed.
|
731
|
-
begin
|
732
|
-
log.close
|
733
|
-
rescue
|
734
|
-
raise if !exception_occurred
|
735
|
-
end
|
736
|
-
end
|
737
|
-
end
|
738
|
-
|
739
|
-
#################
|
740
|
-
end
|
741
|
-
|
742
|
-
def log_analytics_exception(env, exception)
|
743
|
-
log = @analytics_logger.new_transaction(
|
744
|
-
env[PASSENGER_GROUP_NAME],
|
745
|
-
:exceptions,
|
746
|
-
env[PASSENGER_UNION_STATION_KEY])
|
747
|
-
begin
|
748
|
-
request_txn_id = env[PASSENGER_TXN_ID]
|
749
|
-
message = exception.message
|
750
|
-
message = exception.to_s if message.empty?
|
751
|
-
message = [message].pack('m')
|
752
|
-
message.gsub!("\n", "")
|
753
|
-
backtrace_string = [exception.backtrace.join("\n")].pack('m')
|
754
|
-
backtrace_string.gsub!("\n", "")
|
755
|
-
|
756
|
-
log.message("Request transaction ID: #{request_txn_id}")
|
757
|
-
log.message("Message: #{message}")
|
758
|
-
log.message("Class: #{exception.class.name}")
|
759
|
-
log.message("Backtrace: #{backtrace_string}")
|
760
|
-
ensure
|
761
|
-
log.close
|
762
|
-
end
|
763
|
-
end
|
764
|
-
end
|
765
|
-
|
766
|
-
end # module PhusionPassenger
|