passenger 4.0.60 → 5.0.0.beta1
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.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +5 -0
- data/.travis.yml +3 -2
- data/CHANGELOG +31 -53
- data/CONTRIBUTING.md +4 -4
- data/CONTRIBUTORS +0 -1
- data/Gemfile +18 -0
- data/Gemfile.lock +41 -0
- data/Rakefile +16 -0
- data/bin/passenger +2 -2
- data/bin/passenger-install-apache2-module +12 -12
- data/bin/passenger-install-nginx-module +9 -14
- data/bin/passenger-status +125 -87
- data/build/agents.rb +112 -140
- data/build/apache2.rb +4 -9
- data/build/basics.rb +5 -3
- data/build/common_library.rb +1 -0
- data/build/cxx_tests.rb +69 -47
- data/build/debian.rb +4 -2
- data/build/documentation.rb +1 -0
- data/build/integration_tests.rb +28 -43
- data/build/misc.rb +0 -18
- data/build/nginx.rb +2 -6
- data/build/packaging.rb +33 -22
- data/build/preprocessor.rb +2 -4
- data/build/ruby_tests.rb +7 -26
- data/build/test_basics.rb +24 -25
- data/debian.template/control.template +2 -2
- data/debian.template/locations.ini.template +2 -3
- data/debian.template/passenger.install.template +2 -2
- data/debian.template/rules.template +1 -1
- data/dev/ci/run_jenkins.sh +0 -1
- data/dev/ci/run_rpm_tests.sh +3 -0
- data/dev/ci/run_travis.sh +63 -17
- data/dev/copy_boost_headers +22 -6
- data/dev/ruby_server.rb +244 -0
- data/dev/vagrant/provision.sh +3 -1
- data/doc/DebuggingAndStressTesting.md +3 -3
- data/doc/Design and Architecture.txt +5 -6
- data/doc/Packaging.txt.md +35 -6
- data/doc/ServerOptimizationGuide.txt.md +339 -0
- data/doc/Users guide Apache.idmap.txt +177 -187
- data/doc/Users guide Apache.txt +143 -219
- data/doc/Users guide Nginx.idmap.txt +166 -166
- data/doc/Users guide Nginx.txt +265 -223
- data/doc/Users guide Standalone.txt +3 -3
- data/doc/templates/markdown.html.erb +37 -6
- data/doc/users_guide_snippets/environment_variables.txt +1 -1
- data/doc/users_guide_snippets/support_information.txt +1 -1
- data/doc/users_guide_snippets/tips.txt +2 -2
- data/ext/apache2/Configuration.cpp +23 -81
- data/ext/apache2/Configuration.hpp +18 -92
- data/ext/apache2/ConfigurationCommands.cpp +64 -15
- data/ext/apache2/ConfigurationCommands.cpp.erb +8 -4
- data/ext/apache2/ConfigurationFields.hpp +12 -0
- data/ext/apache2/ConfigurationSetters.cpp +73 -1
- data/ext/apache2/ConfigurationSetters.cpp.erb +3 -2
- data/ext/apache2/CreateDirConfig.cpp +6 -0
- data/ext/apache2/DirectoryMapper.h +11 -6
- data/ext/apache2/Hooks.cpp +291 -408
- data/ext/apache2/MergeDirConfig.cpp +42 -0
- data/ext/apache2/SetHeaders.cpp +61 -16
- data/ext/apache2/SetHeaders.cpp.erb +9 -7
- data/ext/boost/container/allocator_traits.hpp +400 -0
- data/ext/boost/container/deque.hpp +2012 -0
- data/ext/boost/container/detail/adaptive_node_pool_impl.hpp +874 -0
- data/ext/boost/container/detail/advanced_insert_int.hpp +369 -0
- data/ext/boost/container/detail/algorithms.hpp +84 -0
- data/ext/boost/container/detail/allocation_type.hpp +54 -0
- data/ext/boost/container/detail/allocator_version_traits.hpp +163 -0
- data/ext/boost/container/detail/config_begin.hpp +49 -0
- data/ext/boost/container/detail/config_end.hpp +17 -0
- data/ext/boost/container/detail/destroyers.hpp +365 -0
- data/ext/boost/container/detail/flat_tree.hpp +1055 -0
- data/ext/boost/container/detail/function_detector.hpp +88 -0
- data/ext/boost/container/detail/iterators.hpp +611 -0
- data/ext/boost/container/detail/math_functions.hpp +113 -0
- data/ext/boost/container/detail/memory_util.hpp +83 -0
- data/ext/boost/container/detail/mpl.hpp +160 -0
- data/ext/boost/container/detail/multiallocation_chain.hpp +286 -0
- data/ext/boost/container/detail/node_alloc_holder.hpp +386 -0
- data/ext/boost/container/detail/node_pool_impl.hpp +365 -0
- data/ext/boost/container/detail/pair.hpp +354 -0
- data/ext/boost/container/detail/pool_common.hpp +52 -0
- data/ext/boost/container/detail/preprocessor.hpp +232 -0
- data/ext/boost/container/detail/transform_iterator.hpp +176 -0
- data/ext/boost/container/detail/tree.hpp +1134 -0
- data/ext/boost/container/detail/type_traits.hpp +210 -0
- data/ext/boost/container/detail/utilities.hpp +1141 -0
- data/ext/boost/container/detail/value_init.hpp +45 -0
- data/ext/boost/container/detail/variadic_templates_tools.hpp +153 -0
- data/ext/boost/container/detail/version_type.hpp +92 -0
- data/ext/boost/container/detail/workaround.hpp +44 -0
- data/ext/boost/container/flat_map.hpp +1674 -0
- data/ext/boost/container/flat_set.hpp +1408 -0
- data/ext/boost/container/list.hpp +1475 -0
- data/ext/boost/container/map.hpp +1508 -0
- data/ext/boost/container/scoped_allocator.hpp +1503 -0
- data/ext/boost/container/scoped_allocator_fwd.hpp +83 -0
- data/ext/boost/container/set.hpp +1280 -0
- data/ext/boost/container/slist.hpp +1706 -0
- data/ext/boost/container/stable_vector.hpp +1869 -0
- data/ext/boost/container/static_vector.hpp +1053 -0
- data/ext/boost/container/string.hpp +2856 -0
- data/ext/boost/container/throw_exception.hpp +110 -0
- data/ext/boost/container/vector.hpp +2671 -0
- data/ext/boost/detail/is_xxx.hpp +61 -0
- data/ext/boost/intrusive/any_hook.hpp +344 -0
- data/ext/boost/intrusive/avl_set.hpp +2528 -0
- data/ext/boost/intrusive/avl_set_hook.hpp +297 -0
- data/ext/boost/intrusive/avltree.hpp +1786 -0
- data/ext/boost/intrusive/avltree_algorithms.hpp +968 -0
- data/ext/boost/intrusive/bs_set_hook.hpp +296 -0
- data/ext/boost/intrusive/circular_list_algorithms.hpp +413 -0
- data/ext/boost/intrusive/circular_slist_algorithms.hpp +404 -0
- data/ext/boost/intrusive/derivation_value_traits.hpp +70 -0
- data/ext/boost/intrusive/detail/any_node_and_algorithms.hpp +297 -0
- data/ext/boost/intrusive/detail/assert.hpp +41 -0
- data/ext/boost/intrusive/detail/avltree_node.hpp +197 -0
- data/ext/boost/intrusive/detail/clear_on_destructor_base.hpp +36 -0
- data/ext/boost/intrusive/detail/common_slist_algorithms.hpp +102 -0
- data/ext/boost/intrusive/detail/config_begin.hpp +52 -0
- data/ext/boost/intrusive/detail/config_end.hpp +15 -0
- data/ext/boost/intrusive/detail/ebo_functor_holder.hpp +95 -0
- data/ext/boost/intrusive/detail/function_detector.hpp +88 -0
- data/ext/boost/intrusive/detail/generic_hook.hpp +209 -0
- data/ext/boost/intrusive/detail/has_member_function_callable_with.hpp +357 -0
- data/ext/boost/intrusive/detail/hashtable_node.hpp +249 -0
- data/ext/boost/intrusive/detail/is_stateful_value_traits.hpp +77 -0
- data/ext/boost/intrusive/detail/list_node.hpp +196 -0
- data/ext/boost/intrusive/detail/memory_util.hpp +288 -0
- data/ext/boost/intrusive/detail/mpl.hpp +383 -0
- data/ext/boost/intrusive/detail/parent_from_member.hpp +97 -0
- data/ext/boost/intrusive/detail/preprocessor.hpp +52 -0
- data/ext/boost/intrusive/detail/rbtree_node.hpp +201 -0
- data/ext/boost/intrusive/detail/slist_node.hpp +166 -0
- data/ext/boost/intrusive/detail/transform_iterator.hpp +173 -0
- data/ext/boost/intrusive/detail/tree_algorithms.hpp +1742 -0
- data/ext/boost/intrusive/detail/tree_node.hpp +199 -0
- data/ext/boost/intrusive/detail/utilities.hpp +858 -0
- data/ext/boost/intrusive/detail/workaround.hpp +22 -0
- data/ext/boost/intrusive/hashtable.hpp +3110 -0
- data/ext/boost/intrusive/intrusive_fwd.hpp +542 -0
- data/ext/boost/intrusive/linear_slist_algorithms.hpp +327 -0
- data/ext/boost/intrusive/link_mode.hpp +46 -0
- data/ext/boost/intrusive/list.hpp +1525 -0
- data/ext/boost/intrusive/list_hook.hpp +290 -0
- data/ext/boost/intrusive/member_value_traits.hpp +70 -0
- data/ext/boost/intrusive/options.hpp +810 -0
- data/ext/boost/intrusive/parent_from_member.hpp +42 -0
- data/ext/boost/intrusive/pointer_plus_bits.hpp +86 -0
- data/ext/boost/intrusive/pointer_traits.hpp +265 -0
- data/ext/boost/intrusive/priority_compare.hpp +39 -0
- data/ext/boost/intrusive/rbtree.hpp +1785 -0
- data/ext/boost/intrusive/rbtree_algorithms.hpp +934 -0
- data/ext/boost/intrusive/set.hpp +2554 -0
- data/ext/boost/intrusive/set_hook.hpp +300 -0
- data/ext/boost/intrusive/sg_set.hpp +2601 -0
- data/ext/boost/intrusive/sgtree.hpp +2009 -0
- data/ext/boost/intrusive/sgtree_algorithms.hpp +807 -0
- data/ext/boost/intrusive/slist.hpp +2219 -0
- data/ext/boost/intrusive/slist_hook.hpp +294 -0
- data/ext/boost/intrusive/splay_set.hpp +2575 -0
- data/ext/boost/intrusive/splay_set_hook.hpp +292 -0
- data/ext/boost/intrusive/splaytree.hpp +1784 -0
- data/ext/boost/intrusive/splaytree_algorithms.hpp +1008 -0
- data/ext/boost/intrusive/treap.hpp +1882 -0
- data/ext/boost/intrusive/treap_algorithms.hpp +919 -0
- data/ext/boost/intrusive/treap_set.hpp +2751 -0
- data/ext/boost/intrusive/trivial_value_traits.hpp +46 -0
- data/ext/boost/intrusive/unordered_set.hpp +2115 -0
- data/ext/boost/intrusive/unordered_set_hook.hpp +434 -0
- data/ext/boost/intrusive_ptr.hpp +18 -0
- data/ext/boost/math/common_factor_ct.hpp +180 -0
- data/ext/boost/math_fwd.hpp +108 -0
- data/ext/boost/move/detail/move_helpers.hpp +175 -0
- data/ext/boost/parameter.hpp +21 -0
- data/ext/boost/parameter/aux_/arg_list.hpp +459 -0
- data/ext/boost/parameter/aux_/cast.hpp +143 -0
- data/ext/boost/parameter/aux_/default.hpp +69 -0
- data/ext/boost/parameter/aux_/is_maybe.hpp +26 -0
- data/ext/boost/parameter/aux_/maybe.hpp +120 -0
- data/ext/boost/parameter/aux_/overloads.hpp +88 -0
- data/ext/boost/parameter/aux_/parameter_requirements.hpp +25 -0
- data/ext/boost/parameter/aux_/parenthesized_type.hpp +119 -0
- data/ext/boost/parameter/aux_/preprocessor/flatten.hpp +115 -0
- data/ext/boost/parameter/aux_/preprocessor/for_each.hpp +103 -0
- data/ext/boost/parameter/aux_/python/invoker.hpp +132 -0
- data/ext/boost/parameter/aux_/python/invoker_iterate.hpp +93 -0
- data/ext/boost/parameter/aux_/result_of0.hpp +36 -0
- data/ext/boost/parameter/aux_/set.hpp +67 -0
- data/ext/boost/parameter/aux_/tag.hpp +38 -0
- data/ext/boost/parameter/aux_/tagged_argument.hpp +188 -0
- data/ext/boost/parameter/aux_/template_keyword.hpp +47 -0
- data/ext/boost/parameter/aux_/unwrap_cv_reference.hpp +97 -0
- data/ext/boost/parameter/aux_/void.hpp +29 -0
- data/ext/boost/parameter/aux_/yesno.hpp +26 -0
- data/ext/boost/parameter/binding.hpp +106 -0
- data/ext/boost/parameter/config.hpp +14 -0
- data/ext/boost/parameter/keyword.hpp +152 -0
- data/ext/boost/parameter/macros.hpp +99 -0
- data/ext/boost/parameter/match.hpp +55 -0
- data/ext/boost/parameter/name.hpp +156 -0
- data/ext/boost/parameter/parameters.hpp +931 -0
- data/ext/boost/parameter/preprocessor.hpp +1178 -0
- data/ext/boost/parameter/python.hpp +735 -0
- data/ext/boost/parameter/value_type.hpp +108 -0
- data/ext/boost/pool/detail/for.m4 +107 -0
- data/ext/boost/pool/detail/guard.hpp +69 -0
- data/ext/boost/pool/detail/mutex.hpp +42 -0
- data/ext/boost/pool/detail/pool_construct.bat +24 -0
- data/ext/boost/pool/detail/pool_construct.ipp +852 -0
- data/ext/boost/pool/detail/pool_construct.m4 +84 -0
- data/ext/boost/pool/detail/pool_construct.sh +12 -0
- data/ext/boost/pool/detail/pool_construct_simple.bat +25 -0
- data/ext/boost/pool/detail/pool_construct_simple.ipp +43 -0
- data/ext/boost/pool/detail/pool_construct_simple.m4 +72 -0
- data/ext/boost/pool/detail/pool_construct_simple.sh +12 -0
- data/ext/boost/pool/object_pool.hpp +287 -0
- data/ext/boost/pool/pool.hpp +1024 -0
- data/ext/boost/pool/pool_alloc.hpp +488 -0
- data/ext/boost/pool/poolfwd.hpp +82 -0
- data/ext/boost/pool/simple_segregated_storage.hpp +377 -0
- data/ext/boost/pool/singleton_pool.hpp +251 -0
- data/ext/boost/preprocessor/arithmetic.hpp +25 -0
- data/ext/boost/preprocessor/arithmetic/detail/div_base.hpp +61 -0
- data/ext/boost/preprocessor/arithmetic/div.hpp +39 -0
- data/ext/boost/preprocessor/arithmetic/mod.hpp +39 -0
- data/ext/boost/preprocessor/arithmetic/mul.hpp +53 -0
- data/ext/boost/preprocessor/array.hpp +32 -0
- data/ext/boost/preprocessor/array/enum.hpp +33 -0
- data/ext/boost/preprocessor/array/insert.hpp +55 -0
- data/ext/boost/preprocessor/array/pop_back.hpp +37 -0
- data/ext/boost/preprocessor/array/pop_front.hpp +38 -0
- data/ext/boost/preprocessor/array/push_back.hpp +33 -0
- data/ext/boost/preprocessor/array/push_front.hpp +33 -0
- data/ext/boost/preprocessor/array/remove.hpp +54 -0
- data/ext/boost/preprocessor/array/replace.hpp +49 -0
- data/ext/boost/preprocessor/array/reverse.hpp +29 -0
- data/ext/boost/preprocessor/array/to_list.hpp +33 -0
- data/ext/boost/preprocessor/array/to_seq.hpp +33 -0
- data/ext/boost/preprocessor/array/to_tuple.hpp +22 -0
- data/ext/boost/preprocessor/assert_msg.hpp +17 -0
- data/ext/boost/preprocessor/comma.hpp +17 -0
- data/ext/boost/preprocessor/comparison.hpp +24 -0
- data/ext/boost/preprocessor/comparison/equal.hpp +34 -0
- data/ext/boost/preprocessor/comparison/greater.hpp +38 -0
- data/ext/boost/preprocessor/comparison/greater_equal.hpp +38 -0
- data/ext/boost/preprocessor/comparison/less.hpp +46 -0
- data/ext/boost/preprocessor/comparison/less_equal.hpp +39 -0
- data/ext/boost/preprocessor/comparison/not_equal.hpp +814 -0
- data/ext/boost/preprocessor/config/limits.hpp +30 -0
- data/ext/boost/preprocessor/control.hpp +22 -0
- data/ext/boost/preprocessor/control/deduce_d.hpp +22 -0
- data/ext/boost/preprocessor/control/detail/dmc/while.hpp +536 -0
- data/ext/boost/preprocessor/control/detail/edg/while.hpp +534 -0
- data/ext/boost/preprocessor/control/detail/msvc/while.hpp +277 -0
- data/ext/boost/preprocessor/control/expr_if.hpp +30 -0
- data/ext/boost/preprocessor/debug.hpp +18 -0
- data/ext/boost/preprocessor/debug/assert.hpp +44 -0
- data/ext/boost/preprocessor/debug/line.hpp +35 -0
- data/ext/boost/preprocessor/detail/dmc/auto_rec.hpp +286 -0
- data/ext/boost/preprocessor/detail/is_nullary.hpp +30 -0
- data/ext/boost/preprocessor/detail/is_unary.hpp +30 -0
- data/ext/boost/preprocessor/detail/null.hpp +17 -0
- data/ext/boost/preprocessor/detail/split.hpp +35 -0
- data/ext/boost/preprocessor/enum_params_with_defaults.hpp +17 -0
- data/ext/boost/preprocessor/enum_shifted.hpp +17 -0
- data/ext/boost/preprocessor/expand.hpp +17 -0
- data/ext/boost/preprocessor/expr_if.hpp +17 -0
- data/ext/boost/preprocessor/facilities.hpp +23 -0
- data/ext/boost/preprocessor/facilities/apply.hpp +34 -0
- data/ext/boost/preprocessor/facilities/expand.hpp +28 -0
- data/ext/boost/preprocessor/facilities/is_1.hpp +23 -0
- data/ext/boost/preprocessor/facilities/is_empty.hpp +43 -0
- data/ext/boost/preprocessor/facilities/is_empty_or_1.hpp +30 -0
- data/ext/boost/preprocessor/for.hpp +17 -0
- data/ext/boost/preprocessor/if.hpp +17 -0
- data/ext/boost/preprocessor/iteration.hpp +19 -0
- data/ext/boost/preprocessor/iteration/detail/bounds/lower3.hpp +99 -0
- data/ext/boost/preprocessor/iteration/detail/bounds/lower4.hpp +99 -0
- data/ext/boost/preprocessor/iteration/detail/bounds/lower5.hpp +99 -0
- data/ext/boost/preprocessor/iteration/detail/bounds/upper3.hpp +99 -0
- data/ext/boost/preprocessor/iteration/detail/bounds/upper4.hpp +99 -0
- data/ext/boost/preprocessor/iteration/detail/bounds/upper5.hpp +99 -0
- data/ext/boost/preprocessor/iteration/detail/finish.hpp +99 -0
- data/ext/boost/preprocessor/iteration/detail/iter/forward3.hpp +1338 -0
- data/ext/boost/preprocessor/iteration/detail/iter/forward4.hpp +1338 -0
- data/ext/boost/preprocessor/iteration/detail/iter/forward5.hpp +1338 -0
- data/ext/boost/preprocessor/iteration/detail/iter/reverse2.hpp +1296 -0
- data/ext/boost/preprocessor/iteration/detail/iter/reverse3.hpp +1296 -0
- data/ext/boost/preprocessor/iteration/detail/iter/reverse4.hpp +1296 -0
- data/ext/boost/preprocessor/iteration/detail/iter/reverse5.hpp +1296 -0
- data/ext/boost/preprocessor/iteration/detail/local.hpp +812 -0
- data/ext/boost/preprocessor/iteration/detail/rlocal.hpp +782 -0
- data/ext/boost/preprocessor/iteration/detail/self.hpp +21 -0
- data/ext/boost/preprocessor/iteration/detail/start.hpp +99 -0
- data/ext/boost/preprocessor/iteration/local.hpp +26 -0
- data/ext/boost/preprocessor/iteration/self.hpp +19 -0
- data/ext/boost/preprocessor/library.hpp +36 -0
- data/ext/boost/preprocessor/limits.hpp +17 -0
- data/ext/boost/preprocessor/list.hpp +37 -0
- data/ext/boost/preprocessor/list/at.hpp +39 -0
- data/ext/boost/preprocessor/list/cat.hpp +42 -0
- data/ext/boost/preprocessor/list/detail/dmc/fold_left.hpp +279 -0
- data/ext/boost/preprocessor/list/detail/edg/fold_left.hpp +536 -0
- data/ext/boost/preprocessor/list/detail/edg/fold_right.hpp +794 -0
- data/ext/boost/preprocessor/list/enum.hpp +41 -0
- data/ext/boost/preprocessor/list/filter.hpp +54 -0
- data/ext/boost/preprocessor/list/first_n.hpp +58 -0
- data/ext/boost/preprocessor/list/for_each.hpp +49 -0
- data/ext/boost/preprocessor/list/for_each_product.hpp +141 -0
- data/ext/boost/preprocessor/list/rest_n.hpp +55 -0
- data/ext/boost/preprocessor/list/size.hpp +58 -0
- data/ext/boost/preprocessor/list/to_array.hpp +123 -0
- data/ext/boost/preprocessor/list/to_seq.hpp +32 -0
- data/ext/boost/preprocessor/list/to_tuple.hpp +38 -0
- data/ext/boost/preprocessor/logical.hpp +29 -0
- data/ext/boost/preprocessor/logical/bitnor.hpp +38 -0
- data/ext/boost/preprocessor/logical/bitor.hpp +38 -0
- data/ext/boost/preprocessor/logical/bitxor.hpp +38 -0
- data/ext/boost/preprocessor/logical/nor.hpp +30 -0
- data/ext/boost/preprocessor/logical/not.hpp +30 -0
- data/ext/boost/preprocessor/logical/or.hpp +30 -0
- data/ext/boost/preprocessor/logical/xor.hpp +30 -0
- data/ext/boost/preprocessor/max.hpp +17 -0
- data/ext/boost/preprocessor/min.hpp +17 -0
- data/ext/boost/preprocessor/punctuation.hpp +20 -0
- data/ext/boost/preprocessor/punctuation/paren_if.hpp +38 -0
- data/ext/boost/preprocessor/repeat_3rd.hpp +17 -0
- data/ext/boost/preprocessor/repeat_from_to.hpp +17 -0
- data/ext/boost/preprocessor/repeat_from_to_2nd.hpp +17 -0
- data/ext/boost/preprocessor/repeat_from_to_3rd.hpp +17 -0
- data/ext/boost/preprocessor/repetition.hpp +32 -0
- data/ext/boost/preprocessor/repetition/deduce_r.hpp +22 -0
- data/ext/boost/preprocessor/repetition/deduce_z.hpp +22 -0
- data/ext/boost/preprocessor/repetition/detail/dmc/for.hpp +536 -0
- data/ext/boost/preprocessor/repetition/detail/edg/for.hpp +534 -0
- data/ext/boost/preprocessor/repetition/detail/msvc/for.hpp +277 -0
- data/ext/boost/preprocessor/repetition/enum_params_with_defaults.hpp +24 -0
- data/ext/boost/preprocessor/repetition/enum_shifted.hpp +68 -0
- data/ext/boost/preprocessor/repetition/enum_shifted_binary_params.hpp +51 -0
- data/ext/boost/preprocessor/repetition/enum_trailing.hpp +63 -0
- data/ext/boost/preprocessor/repetition/enum_trailing_binary_params.hpp +53 -0
- data/ext/boost/preprocessor/selection.hpp +18 -0
- data/ext/boost/preprocessor/selection/max.hpp +39 -0
- data/ext/boost/preprocessor/selection/min.hpp +39 -0
- data/ext/boost/preprocessor/seq.hpp +43 -0
- data/ext/boost/preprocessor/seq/cat.hpp +49 -0
- data/ext/boost/preprocessor/seq/detail/binary_transform.hpp +40 -0
- data/ext/boost/preprocessor/seq/detail/split.hpp +284 -0
- data/ext/boost/preprocessor/seq/filter.hpp +54 -0
- data/ext/boost/preprocessor/seq/first_n.hpp +30 -0
- data/ext/boost/preprocessor/seq/fold_left.hpp +1070 -0
- data/ext/boost/preprocessor/seq/fold_right.hpp +288 -0
- data/ext/boost/preprocessor/seq/for_each.hpp +60 -0
- data/ext/boost/preprocessor/seq/for_each_product.hpp +126 -0
- data/ext/boost/preprocessor/seq/insert.hpp +28 -0
- data/ext/boost/preprocessor/seq/pop_back.hpp +29 -0
- data/ext/boost/preprocessor/seq/pop_front.hpp +27 -0
- data/ext/boost/preprocessor/seq/push_back.hpp +19 -0
- data/ext/boost/preprocessor/seq/push_front.hpp +19 -0
- data/ext/boost/preprocessor/seq/remove.hpp +29 -0
- data/ext/boost/preprocessor/seq/replace.hpp +29 -0
- data/ext/boost/preprocessor/seq/rest_n.hpp +30 -0
- data/ext/boost/preprocessor/seq/reverse.hpp +39 -0
- data/ext/boost/preprocessor/seq/subseq.hpp +28 -0
- data/ext/boost/preprocessor/seq/to_array.hpp +28 -0
- data/ext/boost/preprocessor/seq/to_list.hpp +29 -0
- data/ext/boost/preprocessor/seq/to_tuple.hpp +27 -0
- data/ext/boost/preprocessor/seq/transform.hpp +48 -0
- data/ext/boost/preprocessor/slot.hpp +17 -0
- data/ext/boost/preprocessor/slot/counter.hpp +25 -0
- data/ext/boost/preprocessor/slot/detail/counter.hpp +269 -0
- data/ext/boost/preprocessor/slot/detail/slot1.hpp +267 -0
- data/ext/boost/preprocessor/slot/detail/slot2.hpp +267 -0
- data/ext/boost/preprocessor/slot/detail/slot3.hpp +267 -0
- data/ext/boost/preprocessor/slot/detail/slot4.hpp +267 -0
- data/ext/boost/preprocessor/slot/detail/slot5.hpp +267 -0
- data/ext/boost/preprocessor/tuple.hpp +28 -0
- data/ext/boost/preprocessor/tuple/enum.hpp +22 -0
- data/ext/boost/preprocessor/tuple/reverse.hpp +114 -0
- data/ext/boost/preprocessor/tuple/size.hpp +28 -0
- data/ext/boost/preprocessor/tuple/to_array.hpp +37 -0
- data/ext/boost/preprocessor/tuple/to_seq.hpp +114 -0
- data/ext/boost/preprocessor/variadic.hpp +23 -0
- data/ext/boost/preprocessor/variadic/to_array.hpp +32 -0
- data/ext/boost/preprocessor/variadic/to_list.hpp +25 -0
- data/ext/boost/preprocessor/variadic/to_seq.hpp +25 -0
- data/ext/boost/preprocessor/variadic/to_tuple.hpp +24 -0
- data/ext/boost/preprocessor/while.hpp +17 -0
- data/ext/boost/preprocessor/wstringize.hpp +29 -0
- data/ext/boost/smart_ptr/intrusive_ptr.hpp +324 -0
- data/ext/common/AccountsDatabase.h +3 -4
- data/ext/common/AgentsStarter.cpp +12 -15
- data/ext/common/AgentsStarter.h +54 -120
- data/ext/common/ApplicationPool2/AppTypes.cpp +12 -5
- data/ext/common/ApplicationPool2/AppTypes.h +21 -14
- data/ext/common/ApplicationPool2/Common.h +36 -19
- data/ext/common/ApplicationPool2/DirectSpawner.h +15 -16
- data/ext/common/ApplicationPool2/DummySpawner.h +9 -8
- data/ext/common/ApplicationPool2/ErrorRenderer.h +1 -1
- data/ext/common/ApplicationPool2/Group.h +304 -171
- data/ext/common/ApplicationPool2/Implementation.cpp +234 -125
- data/ext/common/ApplicationPool2/Options.h +50 -62
- data/ext/common/ApplicationPool2/Pool.h +285 -189
- data/ext/common/ApplicationPool2/Process.h +126 -115
- data/ext/common/ApplicationPool2/Session.h +70 -30
- data/ext/common/ApplicationPool2/SmartSpawner.h +19 -18
- data/ext/common/ApplicationPool2/Socket.h +57 -43
- data/ext/common/ApplicationPool2/SpawnObject.h +83 -0
- data/ext/common/ApplicationPool2/Spawner.h +59 -38
- data/ext/common/ApplicationPool2/SpawnerFactory.h +8 -14
- data/ext/common/ApplicationPool2/SuperGroup.h +69 -40
- data/ext/common/BackgroundEventLoop.cpp +48 -1
- data/ext/common/BackgroundEventLoop.h +3 -1
- data/ext/common/Constants.h +30 -8
- data/ext/common/DataStructures/HashedStaticString.h +103 -0
- data/ext/common/DataStructures/LString.h +396 -0
- data/ext/common/DataStructures/StringKeyTable.h +588 -0
- data/ext/common/EventedMessageServer.h +1 -0
- data/ext/common/FileDescriptor.h +5 -0
- data/ext/common/InstanceDirectory.h +240 -0
- data/ext/common/Logging.cpp +38 -13
- data/ext/common/Logging.h +53 -22
- data/ext/common/MemoryKit/mbuf.cpp +413 -0
- data/ext/common/MemoryKit/mbuf.h +266 -0
- data/ext/common/MemoryKit/palloc.cpp +337 -0
- data/ext/common/MemoryKit/palloc.h +121 -0
- data/ext/common/ResourceLocator.h +62 -6
- data/ext/common/SafeLibev.h +4 -4
- data/ext/common/ServerKit/AcceptLoadBalancer.h +275 -0
- data/ext/common/ServerKit/Channel.h +747 -0
- data/ext/common/ServerKit/Client.h +166 -0
- data/ext/common/ServerKit/ClientRef.h +130 -0
- data/ext/common/ServerKit/Context.h +129 -0
- data/ext/common/ServerKit/Errors.h +103 -0
- data/ext/common/ServerKit/FdSinkChannel.h +206 -0
- data/ext/common/ServerKit/FdSourceChannel.h +230 -0
- data/ext/common/ServerKit/FileBufferedChannel.h +1399 -0
- data/ext/common/ServerKit/FileBufferedFdSinkChannel.h +228 -0
- data/ext/common/ServerKit/HeaderTable.h +472 -0
- data/ext/common/ServerKit/Hooks.h +79 -0
- data/ext/common/ServerKit/HttpChunkedBodyParser.h +289 -0
- data/ext/common/ServerKit/HttpChunkedBodyParserState.h +70 -0
- data/ext/common/ServerKit/HttpClient.h +94 -0
- data/ext/common/ServerKit/HttpHeaderParser.h +477 -0
- data/ext/common/ServerKit/HttpHeaderParserState.h +60 -0
- data/ext/common/ServerKit/HttpRequest.h +276 -0
- data/ext/common/ServerKit/HttpRequestRef.h +130 -0
- data/ext/common/ServerKit/HttpServer.h +1152 -0
- data/ext/common/ServerKit/Implementation.cpp +47 -0
- data/ext/common/ServerKit/Server.h +1040 -0
- data/ext/common/ServerKit/http_parser.cpp +2259 -0
- data/ext/common/ServerKit/http_parser.h +330 -0
- data/ext/common/StaticString.h +8 -0
- data/ext/common/Utils.cpp +14 -12
- data/ext/common/Utils.h +9 -103
- data/ext/common/Utils/BufferedIO.h +1 -0
- data/ext/common/Utils/CachedFileStat.hpp +1 -7
- data/ext/common/Utils/DateParsing.h +379 -0
- data/ext/common/Utils/FileChangeChecker.h +3 -9
- data/ext/common/Utils/Hasher.cpp +52 -0
- data/ext/common/Utils/Hasher.h +58 -0
- data/ext/common/Utils/IOUtils.cpp +62 -62
- data/ext/common/Utils/JsonUtils.h +21 -0
- data/ext/common/Utils/OptionParsing.h +75 -0
- data/ext/common/Utils/StrIntUtils.cpp +112 -19
- data/ext/common/Utils/StrIntUtils.h +52 -12
- data/ext/common/Utils/StrIntUtilsNoStrictAliasing.cpp +174 -0
- data/ext/common/Utils/VariantMap.h +18 -7
- data/ext/common/Utils/modp_b64.cpp +290 -0
- data/ext/common/Utils/modp_b64.h +241 -0
- data/ext/common/Utils/modp_b64_data.h +479 -0
- data/ext/common/Utils/sysqueue.h +811 -0
- data/ext/common/agents/Base.cpp +71 -98
- data/ext/common/agents/Base.h +11 -3
- data/ext/common/agents/HelperAgent/AdminServer.h +690 -0
- data/ext/common/agents/HelperAgent/Main.cpp +899 -487
- data/ext/common/agents/HelperAgent/OptionParser.h +311 -0
- data/ext/common/agents/HelperAgent/RequestHandler.h +315 -2548
- data/ext/common/agents/HelperAgent/RequestHandler/AppResponse.h +225 -0
- data/ext/common/agents/HelperAgent/RequestHandler/BufferBody.cpp +93 -0
- data/ext/common/agents/HelperAgent/RequestHandler/CheckoutSession.cpp +346 -0
- data/ext/common/agents/HelperAgent/RequestHandler/Client.h +54 -0
- data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +846 -0
- data/ext/common/agents/HelperAgent/RequestHandler/Hooks.cpp +231 -0
- data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +434 -0
- data/ext/common/agents/HelperAgent/RequestHandler/Request.h +149 -0
- data/ext/common/agents/HelperAgent/RequestHandler/SendRequest.cpp +887 -0
- data/ext/common/agents/HelperAgent/RequestHandler/TurboCaching.h +293 -0
- data/ext/common/agents/HelperAgent/RequestHandler/Utils.cpp +301 -0
- data/ext/common/agents/HelperAgent/ResponseCache.h +624 -0
- data/ext/common/agents/HelperAgent/SystemMetricsTool.cpp +21 -23
- data/ext/common/agents/LoggingAgent/AdminServer.h +369 -0
- data/ext/common/agents/LoggingAgent/LoggingServer.h +1 -0
- data/ext/common/agents/LoggingAgent/Main.cpp +422 -215
- data/ext/common/agents/LoggingAgent/OptionParser.h +167 -0
- data/ext/common/agents/LoggingAgent/RemoteSender.h +3 -3
- data/ext/common/agents/Main.cpp +107 -0
- data/ext/common/agents/SpawnPreparer/Main.cpp +207 -0
- data/ext/common/agents/TempDirToucher/Main.cpp +429 -0
- data/ext/common/agents/Watchdog/AdminServer.h +390 -0
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +7 -5
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +18 -39
- data/ext/common/agents/Watchdog/InstanceDirToucher.cpp +116 -0
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +13 -17
- data/ext/common/agents/Watchdog/Main.cpp +743 -202
- data/ext/libeio/eio.c +17 -0
- data/ext/libeio/eio.h +2 -0
- data/ext/nginx/CacheLocationConfig.c +177 -198
- data/ext/nginx/CacheLocationConfig.c.erb +35 -22
- data/ext/nginx/Configuration.c +402 -236
- data/ext/nginx/Configuration.h +12 -5
- data/ext/nginx/ConfigurationCommands.c +35 -15
- data/ext/nginx/ConfigurationCommands.c.erb +4 -4
- data/ext/nginx/ConfigurationFields.h +9 -5
- data/ext/nginx/ConfigurationFields.h.erb +3 -1
- data/ext/nginx/ContentHandler.c +393 -362
- data/ext/nginx/CreateLocationConfig.c +8 -4
- data/ext/nginx/CreateLocationConfig.c.erb +8 -3
- data/ext/nginx/MergeLocationConfig.c +36 -6
- data/ext/nginx/MergeLocationConfig.c.erb +42 -1
- data/ext/nginx/ngx_http_passenger_module.c +28 -15
- data/ext/oxt/detail/backtrace_disabled.hpp +2 -1
- data/ext/oxt/detail/backtrace_enabled.hpp +15 -2
- data/ext/oxt/implementation.cpp +92 -20
- data/ext/oxt/thread.hpp +5 -0
- data/ext/ruby/extconf.rb +3 -6
- data/ext/ruby/passenger_native_support.c +13 -40
- data/helper-scripts/download_binaries/extconf.rb +4 -4
- data/helper-scripts/meteor-loader.rb +12 -112
- data/helper-scripts/node-loader.js +3 -91
- data/helper-scripts/rack-loader.rb +13 -14
- data/helper-scripts/rack-preloader.rb +16 -17
- data/helper-scripts/wsgi-loader.py +11 -7
- data/lib/phusion_passenger.rb +100 -79
- data/lib/phusion_passenger/abstract_installer.rb +28 -3
- data/lib/phusion_passenger/admin_tools.rb +3 -3
- data/lib/phusion_passenger/admin_tools/instance.rb +207 -0
- data/lib/phusion_passenger/admin_tools/instance_registry.rb +98 -0
- data/lib/phusion_passenger/apache2/config_options.rb +72 -22
- data/lib/phusion_passenger/common_library.rb +79 -14
- data/lib/phusion_passenger/config/about_command.rb +17 -23
- data/lib/phusion_passenger/config/admin_command_command.rb +175 -0
- data/lib/phusion_passenger/config/agent_compiler.rb +170 -0
- data/lib/phusion_passenger/config/command.rb +1 -4
- data/lib/phusion_passenger/config/compile_agent_command.rb +102 -0
- data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +112 -0
- data/lib/phusion_passenger/config/detach_process_command.rb +32 -10
- data/lib/phusion_passenger/config/download_agent_command.rb +285 -0
- data/lib/phusion_passenger/config/download_nginx_engine_command.rb +281 -0
- data/lib/phusion_passenger/config/install_agent_command.rb +174 -0
- data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +231 -0
- data/lib/phusion_passenger/config/installation_utils.rb +241 -0
- data/lib/phusion_passenger/config/list_instances_command.rb +13 -25
- data/lib/phusion_passenger/config/main.rb +43 -14
- data/lib/phusion_passenger/config/nginx_engine_compiler.rb +337 -0
- data/lib/phusion_passenger/config/reopen_logs_command.rb +110 -0
- data/lib/phusion_passenger/config/restart_app_command.rb +61 -14
- data/lib/phusion_passenger/config/system_metrics_command.rb +2 -1
- data/lib/phusion_passenger/config/utils.rb +64 -39
- data/lib/phusion_passenger/config/validate_install_command.rb +2 -2
- data/lib/phusion_passenger/constants.rb +27 -6
- data/lib/phusion_passenger/debug_logging.rb +32 -15
- data/lib/phusion_passenger/loader_shared_helpers.rb +2 -5
- data/lib/phusion_passenger/message_client.rb +21 -22
- data/lib/phusion_passenger/native_support.rb +26 -31
- data/lib/phusion_passenger/nginx/config_options.rb +32 -19
- data/lib/phusion_passenger/packaging.rb +7 -3
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +1 -2
- data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +3 -4
- data/lib/phusion_passenger/platform_info/operating_system.rb +6 -6
- data/lib/phusion_passenger/preloader_shared_helpers.rb +2 -2
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +2 -2
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +168 -65
- data/lib/phusion_passenger/request_handler.rb +47 -82
- data/lib/phusion_passenger/request_handler/thread_handler.rb +46 -10
- data/lib/phusion_passenger/ruby_core_enhancements.rb +25 -77
- data/lib/phusion_passenger/ruby_core_io_enhancements.rb +108 -0
- data/lib/phusion_passenger/standalone/app_finder.rb +39 -59
- data/lib/phusion_passenger/standalone/command.rb +27 -275
- data/lib/phusion_passenger/standalone/command2.rb +292 -0
- data/lib/phusion_passenger/standalone/config_utils.rb +87 -0
- data/lib/phusion_passenger/standalone/control_utils.rb +88 -0
- data/lib/phusion_passenger/standalone/main.rb +69 -71
- data/lib/phusion_passenger/standalone/start2_command.rb +799 -0
- data/lib/phusion_passenger/standalone/start_command.rb +406 -467
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +167 -0
- data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +165 -0
- data/lib/phusion_passenger/standalone/status_command.rb +64 -23
- data/lib/phusion_passenger/standalone/stop_command.rb +69 -32
- data/lib/phusion_passenger/standalone/version_command.rb +1 -5
- data/lib/phusion_passenger/utils.rb +0 -4
- data/lib/phusion_passenger/utils/json.rb +70 -4
- data/lib/phusion_passenger/utils/progress_bar.rb +56 -0
- data/lib/phusion_passenger/utils/tee_input.rb +3 -3
- data/lib/phusion_passenger/utils/unseekable_socket.rb +30 -0
- data/packaging/rpm/nginx_spec/nginx.spec.template +4 -3
- data/packaging/rpm/passenger_spec/passenger.spec.template +6 -10
- data/packaging/rpm/setup-system +2 -1
- data/resources/oss-binaries.phusionpassenger.com.crt +208 -0
- data/resources/templates/config/agent_compiler/confirm_enable_optimizations.txt.erb +5 -0
- data/resources/templates/config/installation_utils/cannot_create_user_support_binaries_dir.txt.erb +15 -0
- data/resources/templates/config/installation_utils/download_tool_missing.txt.erb +7 -0
- data/resources/templates/config/installation_utils/passenger_not_installed_as_root.txt.erb +12 -0
- data/resources/templates/config/installation_utils/support_binaries_dir_not_writable_despite_running_as_root.txt.erb +13 -0
- data/resources/templates/config/installation_utils/unexpected_filesystem_problem.txt.erb +16 -0
- data/{packaging/debian/debian_specs/passenger/patches/series → resources/templates/config/installation_utils/user_support_binaries_dir_not_writable.txt.erb} +0 -0
- data/resources/templates/nginx/nginx_module_sources_not_available.txt.erb +2 -2
- data/resources/templates/standalone/config.erb +14 -16
- data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +1 -1
- data/test/.rspec +1 -0
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +20 -17
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +0 -14
- data/test/cxx/ApplicationPool2/PoolTest.cpp +113 -90
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +18 -27
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +51 -53
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +55 -57
- data/test/cxx/BufferedIOTest.cpp +40 -40
- data/test/cxx/CxxTestMain.cpp +4 -22
- data/test/cxx/DataStructures/LStringTest.cpp +275 -0
- data/test/cxx/DataStructures/StringKeyTableTest.cpp +199 -0
- data/test/cxx/MemoryKit/MbufTest.cpp +213 -0
- data/test/cxx/MessageServerTest.cpp +62 -55
- data/test/cxx/RequestHandlerTest.cpp +26 -27
- data/test/cxx/ServerKit/ChannelTest.cpp +1467 -0
- data/test/cxx/ServerKit/FileBufferedChannelTest.cpp +817 -0
- data/test/cxx/ServerKit/HeaderTableTest.cpp +171 -0
- data/test/cxx/ServerKit/HttpServerTest.cpp +1503 -0
- data/test/cxx/ServerKit/ServerTest.cpp +408 -0
- data/test/cxx/TestSupport.cpp +51 -15
- data/test/cxx/TestSupport.h +31 -21
- data/test/cxx/UnionStationTest.cpp +121 -122
- data/test/cxx/UtilsTest.cpp +9 -33
- data/test/integration_tests/apache2_tests.rb +65 -27
- data/test/integration_tests/downloaded_binaries_tests.rb +30 -6
- data/test/integration_tests/native_packaging_spec.rb +32 -17
- data/test/integration_tests/nginx_tests.rb +28 -10
- data/test/integration_tests/shared/example_webapp_tests.rb +40 -27
- data/test/integration_tests/standalone_tests.rb +232 -169
- data/test/ruby/debug_logging_spec.rb +44 -40
- data/test/ruby/rails3.0/preloader_spec.rb +1 -1
- data/test/ruby/rails3.1/preloader_spec.rb +1 -1
- data/test/ruby/rails3.2/preloader_spec.rb +1 -1
- data/test/ruby/rails4.0/preloader_spec.rb +1 -1
- data/test/ruby/rails4.1/preloader_spec.rb +1 -1
- data/test/ruby/request_handler_spec.rb +62 -24
- data/test/ruby/shared/loader_sharedspec.rb +10 -9
- data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +23 -22
- data/test/ruby/spec_helper.rb +2 -11
- data/test/ruby/standalone/runtime_installer_spec.rb +15 -13
- data/test/ruby/union_station_spec.rb +45 -40
- data/test/ruby/utils/tee_input_spec.rb +5 -5
- data/test/ruby/utils_spec.rb +3 -39
- data/test/stub/apache2/httpd.conf.erb +5 -2
- data/test/stub/nginx/nginx.conf.erb +3 -1
- data/test/support/apache2_controller.rb +25 -25
- data/test/support/nginx_controller.rb +14 -14
- data/test/support/test_helper.rb +74 -75
- metadata +439 -643
- metadata.gz.asc +7 -7
- data/ext/common/MultiLibeio.cpp +0 -204
- data/ext/common/MultiLibeio.h +0 -67
- data/ext/common/ServerInstanceDir.h +0 -402
- data/ext/common/Utils/Base64.cpp +0 -143
- data/ext/common/Utils/Base64.h +0 -83
- data/ext/common/Utils/HttpHeaderBufferer.h +0 -184
- data/ext/common/Utils/PriorityQueue.h +0 -54
- data/ext/common/Utils/StreamBoyerMooreHorspool.h +0 -512
- data/ext/common/Utils/fib.c +0 -699
- data/ext/common/Utils/fib.h +0 -101
- data/ext/common/Utils/fibpriv.h +0 -67
- data/ext/common/agents/EnvPrinter.c +0 -16
- data/ext/common/agents/HelperAgent/AgentOptions.h +0 -109
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +0 -732
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +0 -294
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +0 -457
- data/ext/common/agents/LoggingAgent/AdminController.h +0 -96
- data/ext/common/agents/SpawnPreparer.cpp +0 -206
- data/ext/common/agents/TempDirToucher.c +0 -383
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +0 -116
- data/helper-scripts/classic-rails-loader.rb +0 -166
- data/helper-scripts/classic-rails-preloader.rb +0 -193
- data/lib/phusion_passenger/admin_tools/server_instance.rb +0 -339
- data/lib/phusion_passenger/classic_rails/cgi_fixed.rb +0 -68
- data/lib/phusion_passenger/classic_rails/thread_handler_extension.rb +0 -40
- data/lib/phusion_passenger/platform_info/openssl.rb +0 -61
- data/lib/phusion_passenger/standalone/config_file.rb +0 -119
- data/lib/phusion_passenger/standalone/help_command.rb +0 -57
- data/lib/phusion_passenger/standalone/runtime_installer.rb +0 -712
- data/lib/phusion_passenger/standalone/runtime_locator.rb +0 -170
- data/lib/phusion_passenger/standalone/utils.rb +0 -58
- data/lib/phusion_passenger/utils/tmpdir.rb +0 -69
- data/packaging/debian/LICENSE.md +0 -19
- data/packaging/debian/README.md +0 -320
- data/packaging/debian/Vagrantfile +0 -25
- data/packaging/debian/build +0 -210
- data/packaging/debian/debian_specs/nginx/changelog +0 -1989
- data/packaging/debian/debian_specs/nginx/compat.erb +0 -5
- data/packaging/debian/debian_specs/nginx/conf/fastcgi.conf +0 -25
- data/packaging/debian/debian_specs/nginx/conf/fastcgi_params +0 -24
- data/packaging/debian/debian_specs/nginx/conf/koi-utf +0 -109
- data/packaging/debian/debian_specs/nginx/conf/koi-win +0 -103
- data/packaging/debian/debian_specs/nginx/conf/mime.types +0 -89
- data/packaging/debian/debian_specs/nginx/conf/nginx.conf.erb +0 -97
- data/packaging/debian/debian_specs/nginx/conf/proxy_params +0 -4
- data/packaging/debian/debian_specs/nginx/conf/scgi_params +0 -16
- data/packaging/debian/debian_specs/nginx/conf/sites-available/default.erb +0 -93
- data/packaging/debian/debian_specs/nginx/conf/snippets/fastcgi-php.conf +0 -13
- data/packaging/debian/debian_specs/nginx/conf/snippets/snakeoil.conf +0 -5
- data/packaging/debian/debian_specs/nginx/conf/uwsgi_params +0 -16
- data/packaging/debian/debian_specs/nginx/conf/win-utf +0 -125
- data/packaging/debian/debian_specs/nginx/control.erb +0 -226
- data/packaging/debian/debian_specs/nginx/copyright +0 -196
- data/packaging/debian/debian_specs/nginx/debian-full.lintian-overrides +0 -1
- data/packaging/debian/debian_specs/nginx/gbp.conf +0 -2
- data/packaging/debian/debian_specs/nginx/help/docs/fcgiwrap +0 -14
- data/packaging/debian/debian_specs/nginx/help/docs/php +0 -119
- data/packaging/debian/debian_specs/nginx/help/docs/support-irc +0 -28
- data/packaging/debian/debian_specs/nginx/help/docs/upstream +0 -51
- data/packaging/debian/debian_specs/nginx/help/examples/drupal +0 -114
- data/packaging/debian/debian_specs/nginx/help/examples/http +0 -59
- data/packaging/debian/debian_specs/nginx/help/examples/mail +0 -30
- data/packaging/debian/debian_specs/nginx/help/examples/mailman +0 -59
- data/packaging/debian/debian_specs/nginx/help/examples/nginx.conf +0 -34
- data/packaging/debian/debian_specs/nginx/help/examples/nginx_modsite +0 -162
- data/packaging/debian/debian_specs/nginx/help/examples/virtual_hosts +0 -155
- data/packaging/debian/debian_specs/nginx/help/examples/wordpress +0 -74
- data/packaging/debian/debian_specs/nginx/helpers.rb +0 -41
- data/packaging/debian/debian_specs/nginx/index-debian.html.in +0 -32
- data/packaging/debian/debian_specs/nginx/index-ubuntu.html.in +0 -32
- data/packaging/debian/debian_specs/nginx/index.html.erb +0 -10
- data/packaging/debian/debian_specs/nginx/modules/README.Modules-versions +0 -65
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/README.markdown +0 -510
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/config +0 -5
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/doc/HttpHeadersMoreModule.wiki +0 -395
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ddebug.h +0 -119
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_filter_module.c +0 -348
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_filter_module.h +0 -80
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_headers_in.c +0 -826
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_headers_in.h +0 -26
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_headers_out.c +0 -716
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_headers_out.h +0 -26
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_util.c +0 -380
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/src/ngx_http_headers_more_util.h +0 -52
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/util/build.sh +0 -32
- data/packaging/debian/debian_specs/nginx/modules/headers-more-nginx-module/valgrind.suppress +0 -215
- data/packaging/debian/debian_specs/nginx/modules/nginx-auth-pam/ChangeLog +0 -35
- data/packaging/debian/debian_specs/nginx/modules/nginx-auth-pam/LICENSE +0 -25
- data/packaging/debian/debian_specs/nginx/modules/nginx-auth-pam/README.md +0 -93
- data/packaging/debian/debian_specs/nginx/modules/nginx-auth-pam/config +0 -4
- data/packaging/debian/debian_specs/nginx/modules/nginx-auth-pam/ngx_http_auth_pam_module.c +0 -462
- data/packaging/debian/debian_specs/nginx/modules/nginx-cache-purge/CHANGES +0 -66
- data/packaging/debian/debian_specs/nginx/modules/nginx-cache-purge/LICENSE +0 -26
- data/packaging/debian/debian_specs/nginx/modules/nginx-cache-purge/README.md +0 -171
- data/packaging/debian/debian_specs/nginx/modules/nginx-cache-purge/TODO.md +0 -7
- data/packaging/debian/debian_specs/nginx/modules/nginx-cache-purge/config +0 -21
- data/packaging/debian/debian_specs/nginx/modules/nginx-cache-purge/ngx_cache_purge_module.c +0 -1803
- data/packaging/debian/debian_specs/nginx/modules/nginx-dav-ext-module/README +0 -29
- data/packaging/debian/debian_specs/nginx/modules/nginx-dav-ext-module/config +0 -9
- data/packaging/debian/debian_specs/nginx/modules/nginx-dav-ext-module/ngx_http_dav_ext_module.c +0 -824
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/README +0 -139
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/README_AUTO_LIB +0 -395
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/TODO +0 -1
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/actions/array +0 -10
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/actions/palloc +0 -8
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/build +0 -597
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/action_replacements +0 -5
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/action_types +0 -12
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/conf_args +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/conf_locs +0 -25
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/conf_macros +0 -35
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/contexts +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/header_files +0 -3
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/headers +0 -4
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/module_dependencies +0 -5
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/modules_optional +0 -15
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/data/prefixes +0 -2
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/src/array.h +0 -7
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/src/conf_cmd_basic.h +0 -43
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/src/conf_merge.h +0 -78
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/src/palloc.h +0 -6
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/auto/text/autogen +0 -12
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/config +0 -49
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/docs/core/action_macros +0 -63
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/docs/core/conf_cmds +0 -62
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/docs/modules/set_var +0 -124
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/docs/patches/more_logging_info +0 -48
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/docs/upstream/list +0 -45
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/examples/README +0 -12
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/examples/http/set_var/config +0 -4
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/examples/http/set_var/ngx_http_set_var_examples_module.c +0 -136
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/ngx_auto_lib_core +0 -797
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/notes/CHANGES +0 -17
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/notes/LICENSE +0 -24
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_array.h +0 -113
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_conf_cmd_basic.h +0 -2203
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_conf_cmd_extra.h +0 -5423
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_conf_merge.h +0 -227
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_config.c +0 -72
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_config.h +0 -98
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_includes.h +0 -66
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/objs/ndk_palloc.h +0 -112
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/patches/auto_config +0 -16
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/patches/expose_rewrite_functions +0 -291
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/patches/rewrite_phase_handler +0 -19
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/hash/md5.h +0 -117
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/hash/murmurhash2.c +0 -77
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/hash/sha.h +0 -200
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk.c +0 -155
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk.h +0 -58
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_buf.c +0 -43
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_buf.h +0 -5
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_complex_path.c +0 -129
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_complex_path.h +0 -30
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_complex_value.c +0 -192
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_complex_value.h +0 -21
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_conf_file.c +0 -396
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_conf_file.h +0 -44
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_debug.c +0 -72
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_debug.h +0 -171
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_encoding.c +0 -57
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_encoding.h +0 -12
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_hash.c +0 -82
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_hash.h +0 -45
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_http.c +0 -138
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_http.h +0 -3
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_http_headers.h +0 -35
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_log.c +0 -3
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_log.h +0 -165
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_parse.h +0 -67
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_path.c +0 -583
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_path.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_process.c +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_process.h +0 -12
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_regex.c +0 -215
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_regex.h +0 -7
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_rewrite.c +0 -103
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_rewrite.h +0 -26
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_set_var.c +0 -602
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_set_var.h +0 -44
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_string.c +0 -434
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_string.h +0 -37
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_string_util.h +0 -14
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_upstream_list.c +0 -205
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_upstream_list.h +0 -27
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_uri.c +0 -45
- data/packaging/debian/debian_specs/nginx/modules/nginx-development-kit/src/ndk_uri.h +0 -6
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/LICENSE +0 -25
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/README.markdown +0 -1850
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/config +0 -5
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/doc/HttpEchoModule.wiki +0 -1558
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ddebug.h +0 -109
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_echo.c +0 -344
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_echo.h +0 -25
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_filter.c +0 -282
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_filter.h +0 -15
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_foreach.c +0 -183
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_foreach.h +0 -16
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_handler.c +0 -429
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_handler.h +0 -18
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_location.c +0 -178
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_location.h +0 -13
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_module.c +0 -667
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_module.h +0 -137
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_request_info.c +0 -452
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_request_info.h +0 -31
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_sleep.c +0 -208
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_sleep.h +0 -16
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_subrequest.c +0 -788
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_subrequest.h +0 -19
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_timer.c +0 -96
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_timer.h +0 -13
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_util.c +0 -298
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_util.h +0 -58
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_var.c +0 -110
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/src/ngx_http_echo_var.h +0 -9
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/util/build.sh +0 -45
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/util/releng +0 -8
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/util/wiki2pod.pl +0 -131
- data/packaging/debian/debian_specs/nginx/modules/nginx-echo/valgrind.suppress +0 -38
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/LICENCE +0 -24
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/README +0 -206
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/changelog.txt +0 -54
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/config +0 -26
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/protocol.txt +0 -191
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/ngx_http_push_defs.c +0 -59
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/ngx_http_push_defs.h +0 -73
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/ngx_http_push_module.c +0 -783
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/ngx_http_push_module.h +0 -31
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/ngx_http_push_module_setup.c +0 -361
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/ngx_http_push_types.h +0 -120
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/memory/store.c +0 -1180
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/memory/store.h +0 -1
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/ngx_http_push_module_ipc.c +0 -146
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/ngx_http_push_module_ipc.h +0 -5
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/ngx_http_push_store.h +0 -51
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/ngx_rwlock.c +0 -178
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/ngx_rwlock.h +0 -5
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/rbtree_util.c +0 -246
- data/packaging/debian/debian_specs/nginx/modules/nginx-http-push/src/store/rbtree_util.h +0 -9
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/Changes +0 -51
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/README.markdown +0 -6954
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/config +0 -363
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/doc/HttpLuaModule.wiki +0 -5898
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/dtrace/ngx_lua_provider.d +0 -61
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/misc/recv-until-pm/Makefile +0 -3
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/misc/recv-until-pm/lib/RecvUntil.pm +0 -138
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/misc/recv-until-pm/t/sanity.t +0 -140
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/api/ngx_http_lua_api.h +0 -52
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ddebug.h +0 -82
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_accessby.c +0 -377
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_accessby.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_api.c +0 -77
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_args.c +0 -537
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_args.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_bodyfilterby.c +0 -632
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_bodyfilterby.h +0 -31
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_cache.c +0 -296
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_cache.h +0 -24
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_capturefilter.c +0 -175
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_capturefilter.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_clfactory.c +0 -887
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_clfactory.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_common.h +0 -478
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_config.c +0 -67
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_config.h +0 -19
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_consts.c +0 -148
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_consts.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_contentby.c +0 -369
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_contentby.h +0 -26
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_control.c +0 -483
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_control.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_coroutine.c +0 -379
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_coroutine.h +0 -23
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_ctx.c +0 -216
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_ctx.h +0 -23
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_directive.c +0 -1081
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_directive.h +0 -56
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_exception.c +0 -58
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_exception.h +0 -33
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headerfilterby.c +0 -302
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headerfilterby.h +0 -29
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headers.c +0 -1370
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headers.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headers_in.c +0 -782
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headers_in.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headers_out.c +0 -625
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_headers_out.h +0 -23
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_initby.c +0 -42
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_initby.h +0 -23
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_initworkerby.c +0 -320
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_initworkerby.h +0 -25
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_log.c +0 -300
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_log.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_logby.c +0 -227
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_logby.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_misc.c +0 -252
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_misc.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_module.c +0 -924
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_ndk.c +0 -184
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_ndk.h +0 -21
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_output.c +0 -794
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_output.h +0 -28
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_pcrefix.c +0 -106
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_pcrefix.h +0 -23
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_phase.c +0 -94
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_phase.h +0 -13
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_probe.h +0 -85
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_regex.c +0 -2468
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_regex.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_req_body.c +0 -1169
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_req_body.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_req_method.c +0 -252
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_req_method.h +0 -19
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_rewriteby.c +0 -351
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_rewriteby.h +0 -22
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_script.c +0 -538
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_script.h +0 -86
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_setby.c +0 -216
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_setby.h +0 -15
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_shdict.c +0 -1844
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_shdict.h +0 -52
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_sleep.c +0 -191
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_sleep.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_socket_tcp.c +0 -5314
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_socket_tcp.h +0 -156
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_socket_udp.c +0 -1624
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_socket_udp.h +0 -56
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_string.c +0 -704
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_string.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_subrequest.c +0 -1741
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_subrequest.h +0 -46
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_time.c +0 -278
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_time.h +0 -21
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_timer.c +0 -661
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_timer.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_uri.c +0 -110
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_uri.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_uthread.c +0 -283
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_uthread.h +0 -36
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_util.c +0 -3972
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_util.h +0 -423
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_variable.c +0 -499
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_variable.h +0 -20
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_worker.c +0 -64
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/src/ngx_http_lua_worker.h +0 -17
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/tapset/ngx_lua.stp +0 -5
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/build.sh +0 -39
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/build2.sh +0 -55
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/fix-comments +0 -27
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/gdbinit +0 -415
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/ngx-links +0 -62
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/reindex +0 -64
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/releng +0 -8
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/retab +0 -8
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/revim +0 -102
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/run_test.sh +0 -10
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/util/update-readme.sh +0 -4
- data/packaging/debian/debian_specs/nginx/modules/nginx-lua/valgrind.suppress +0 -144
- data/packaging/debian/debian_specs/nginx/modules/nginx-upload-progress/CHANGES +0 -107
- data/packaging/debian/debian_specs/nginx/modules/nginx-upload-progress/LICENSE +0 -25
- data/packaging/debian/debian_specs/nginx/modules/nginx-upload-progress/Makefile +0 -8
- data/packaging/debian/debian_specs/nginx/modules/nginx-upload-progress/README +0 -329
- data/packaging/debian/debian_specs/nginx/modules/nginx-upload-progress/config +0 -3
- data/packaging/debian/debian_specs/nginx/modules/nginx-upload-progress/ngx_http_uploadprogress_module.c +0 -1774
- data/packaging/debian/debian_specs/nginx/modules/nginx-upstream-fair/README +0 -53
- data/packaging/debian/debian_specs/nginx/modules/nginx-upstream-fair/config +0 -3
- data/packaging/debian/debian_specs/nginx/modules/nginx-upstream-fair/ngx_http_upstream_fair_module.c +0 -1356
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/CHANGELOG.md +0 -37
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/HACKING.md +0 -24
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/LICENSE +0 -20
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/README.rst +0 -182
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/config +0 -8
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/nginx-0.6-support.patch +0 -23
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/ngx_http_fancyindex_module.c +0 -1305
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/template.awk +0 -52
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/template.h +0 -103
- data/packaging/debian/debian_specs/nginx/modules/ngx-fancyindex/template.html +0 -102
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/CHANGES +0 -37
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/README +0 -141
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/config +0 -3
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/doc/README.google_code_home_page.wiki +0 -120
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/doc/README.html +0 -199
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/doc/README.wiki +0 -123
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/ngx_http_subs_filter_module.c +0 -1298
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/README +0 -275
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/AutoInstall.pm +0 -820
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install.pm +0 -470
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/AutoInstall.pm +0 -82
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/Base.pm +0 -83
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/Can.pm +0 -81
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/Fetch.pm +0 -93
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/Include.pm +0 -34
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/Makefile.pm +0 -415
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/Metadata.pm +0 -716
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/TestBase.pm +0 -29
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/Win32.pm +0 -64
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Module/Install/WriteAll.pm +0 -63
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Spiffy.pm +0 -539
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Test/Base.pm +0 -682
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Test/Base/Filter.pm +0 -341
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Test/Builder.pm +0 -1413
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Test/Builder/Module.pm +0 -81
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/inc/Test/More.pm +0 -735
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/lib/Test/Nginx.pm +0 -315
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/lib/Test/Nginx/LWP.pm +0 -524
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/lib/Test/Nginx/Socket.pm +0 -1749
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/lib/Test/Nginx/Util.pm +0 -874
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/t/subs.t +0 -136
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/t/subs_capture.t +0 -32
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/t/subs_fix_string.t +0 -32
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/t/subs_regex.t +0 -108
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/t/subs_types.t +0 -59
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/test/test.sh +0 -5
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/util/update-readme.sh +0 -7
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/util/wiki2google_code_homepage.pl +0 -29
- data/packaging/debian/debian_specs/nginx/modules/ngx_http_substitutions_filter_module/util/wiki2pod.pl +0 -129
- data/packaging/debian/debian_specs/nginx/nginx-common.NEWS +0 -135
- data/packaging/debian/debian_specs/nginx/nginx-common.README.Debian +0 -45
- data/packaging/debian/debian_specs/nginx/nginx-common.dirs.erb +0 -32
- data/packaging/debian/debian_specs/nginx/nginx-common.install +0 -3
- data/packaging/debian/debian_specs/nginx/nginx-common.lintian-overrides +0 -2
- data/packaging/debian/debian_specs/nginx/nginx-common.manpages +0 -1
- data/packaging/debian/debian_specs/nginx/nginx-common.nginx.default +0 -10
- data/packaging/debian/debian_specs/nginx/nginx-common.nginx.init.erb +0 -214
- data/packaging/debian/debian_specs/nginx/nginx-common.nginx.logrotate +0 -18
- data/packaging/debian/debian_specs/nginx/nginx-common.nginx.service.erb +0 -37
- data/packaging/debian/debian_specs/nginx/nginx-common.postinst.erb +0 -66
- data/packaging/debian/debian_specs/nginx/nginx-common.postrm.erb +0 -46
- data/packaging/debian/debian_specs/nginx/nginx-common.preinst +0 -47
- data/packaging/debian/debian_specs/nginx/nginx-common.prerm.erb +0 -28
- data/packaging/debian/debian_specs/nginx/nginx-doc.docs +0 -2
- data/packaging/debian/debian_specs/nginx/nginx-doc.examples +0 -1
- data/packaging/debian/debian_specs/nginx/nginx-extras.install.erb +0 -17
- data/packaging/debian/debian_specs/nginx/nginx-extras.lintian-overrides +0 -1
- data/packaging/debian/debian_specs/nginx/nginx-extras.postinst.erb +0 -44
- data/packaging/debian/debian_specs/nginx/nginx-extras.prerm +0 -22
- data/packaging/debian/debian_specs/nginx/nginx.1 +0 -47
- data/packaging/debian/debian_specs/nginx/patches/perl-use-dpkg-buildflags.patch +0 -23
- data/packaging/debian/debian_specs/nginx/patches/series +0 -1
- data/packaging/debian/debian_specs/nginx/rules.erb +0 -185
- data/packaging/debian/debian_specs/nginx/source/format +0 -1
- data/packaging/debian/debian_specs/nginx/tests/control +0 -4
- data/packaging/debian/debian_specs/nginx/ufw/nginx +0 -14
- data/packaging/debian/debian_specs/nginx/upstream/signing-key.asc +0 -34
- data/packaging/debian/debian_specs/nginx/watch +0 -3
- data/packaging/debian/debian_specs/passenger/README.Debian +0 -12
- data/packaging/debian/debian_specs/passenger/changelog +0 -316
- data/packaging/debian/debian_specs/passenger/compat +0 -1
- data/packaging/debian/debian_specs/passenger/control.erb +0 -123
- data/packaging/debian/debian_specs/passenger/copyright +0 -385
- data/packaging/debian/debian_specs/passenger/helpers.rb +0 -24
- data/packaging/debian/debian_specs/passenger/libapache2-mod-passenger.install +0 -3
- data/packaging/debian/debian_specs/passenger/libapache2-mod-passenger.postinst +0 -36
- data/packaging/debian/debian_specs/passenger/libapache2-mod-passenger.prerm +0 -15
- data/packaging/debian/debian_specs/passenger/locations.ini.erb +0 -14
- data/packaging/debian/debian_specs/passenger/passenger-dev.install.erb +0 -3
- data/packaging/debian/debian_specs/passenger/passenger-doc.install.erb +0 -2
- data/packaging/debian/debian_specs/passenger/passenger.conf +0 -6
- data/packaging/debian/debian_specs/passenger/passenger.docs +0 -4
- data/packaging/debian/debian_specs/passenger/passenger.install.erb +0 -16
- data/packaging/debian/debian_specs/passenger/passenger.load +0 -3
- data/packaging/debian/debian_specs/passenger/passenger.manpages +0 -3
- data/packaging/debian/debian_specs/passenger/passenger_free_ruby.c +0 -29
- data/packaging/debian/debian_specs/passenger/passenger_ruby_utils.c +0 -54
- data/packaging/debian/debian_specs/passenger/passenger_system_ruby.c.erb +0 -37
- data/packaging/debian/debian_specs/passenger/rules.erb +0 -84
- data/packaging/debian/debian_specs/passenger/source/format +0 -1
- data/packaging/debian/debian_specs/passenger_enterprise/README.Debian +0 -12
- data/packaging/debian/debian_specs/passenger_enterprise/changelog +0 -316
- data/packaging/debian/debian_specs/passenger_enterprise/compat +0 -1
- data/packaging/debian/debian_specs/passenger_enterprise/control.erb +0 -123
- data/packaging/debian/debian_specs/passenger_enterprise/copyright +0 -385
- data/packaging/debian/debian_specs/passenger_enterprise/helpers.rb +0 -2
- data/packaging/debian/debian_specs/passenger_enterprise/libapache2-mod-passenger-enterprise.install +0 -3
- data/packaging/debian/debian_specs/passenger_enterprise/libapache2-mod-passenger-enterprise.postinst +0 -36
- data/packaging/debian/debian_specs/passenger_enterprise/libapache2-mod-passenger-enterprise.prerm +0 -15
- data/packaging/debian/debian_specs/passenger_enterprise/locations.ini.erb +0 -14
- data/packaging/debian/debian_specs/passenger_enterprise/passenger-enterprise-dev.install.erb +0 -3
- data/packaging/debian/debian_specs/passenger_enterprise/passenger-enterprise-doc.install.erb +0 -2
- data/packaging/debian/debian_specs/passenger_enterprise/passenger-enterprise.docs +0 -4
- data/packaging/debian/debian_specs/passenger_enterprise/passenger-enterprise.install.erb +0 -14
- data/packaging/debian/debian_specs/passenger_enterprise/passenger-enterprise.manpages +0 -3
- data/packaging/debian/debian_specs/passenger_enterprise/passenger.conf +0 -6
- data/packaging/debian/debian_specs/passenger_enterprise/passenger.load +0 -3
- data/packaging/debian/debian_specs/passenger_enterprise/passenger_free_ruby.c.erb +0 -1
- data/packaging/debian/debian_specs/passenger_enterprise/passenger_ruby_utils.c.erb +0 -1
- data/packaging/debian/debian_specs/passenger_enterprise/passenger_system_ruby.c.erb +0 -1
- data/packaging/debian/debian_specs/passenger_enterprise/patches/series +0 -0
- data/packaging/debian/debian_specs/passenger_enterprise/rules.erb +0 -84
- data/packaging/debian/debian_specs/passenger_enterprise/source/format +0 -1
- data/packaging/debian/docker_images/Makefile +0 -38
- data/packaging/debian/docker_images/buildbox/CONTAINER_VERSION.txt +0 -0
- data/packaging/debian/docker_images/buildbox/Dockerfile +0 -3
- data/packaging/debian/docker_images/buildbox/Gemfile +0 -9
- data/packaging/debian/docker_images/buildbox/Gemfile.lock +0 -42
- data/packaging/debian/docker_images/buildbox/install.sh +0 -85
- data/packaging/debian/docker_images/buildbox/pbuilderrc +0 -4
- data/packaging/debian/docker_images/buildbox/sudoers.conf +0 -6
- data/packaging/debian/docker_images/setup-buildbox-docker-image +0 -7
- data/packaging/debian/docker_images/setup-testbox-docker-image-debian-6 +0 -7
- data/packaging/debian/docker_images/setup-testbox-docker-image-debian-7 +0 -7
- data/packaging/debian/docker_images/setup-testbox-docker-image-debian-8 +0 -7
- data/packaging/debian/docker_images/setup-testbox-docker-image-ubuntu-12.04 +0 -7
- data/packaging/debian/docker_images/setup-testbox-docker-image-ubuntu-14.04 +0 -7
- data/packaging/debian/docker_images/setup-testbox-docker-image-ubuntu-15.04 +0 -7
- data/packaging/debian/docker_images/setup-testbox-docker-image-ubuntu-15.10 +0 -7
- data/packaging/debian/docker_images/testbox-debian-6/Dockerfile +0 -3
- data/packaging/debian/docker_images/testbox-debian-6/Gemfile +0 -2
- data/packaging/debian/docker_images/testbox-debian-6/Gemfile.lock +0 -23
- data/packaging/debian/docker_images/testbox-debian-6/argparse.py +0 -2374
- data/packaging/debian/docker_images/testbox-debian-6/install.sh +0 -78
- data/packaging/debian/docker_images/testbox-debian-7/Dockerfile +0 -3
- data/packaging/debian/docker_images/testbox-debian-7/Gemfile +0 -2
- data/packaging/debian/docker_images/testbox-debian-7/Gemfile.lock +0 -23
- data/packaging/debian/docker_images/testbox-debian-7/install.sh +0 -71
- data/packaging/debian/docker_images/testbox-debian-8/Dockerfile +0 -3
- data/packaging/debian/docker_images/testbox-debian-8/Gemfile +0 -2
- data/packaging/debian/docker_images/testbox-debian-8/Gemfile.lock +0 -23
- data/packaging/debian/docker_images/testbox-debian-8/install.sh +0 -70
- data/packaging/debian/docker_images/testbox-ubuntu-12.04/Dockerfile +0 -3
- data/packaging/debian/docker_images/testbox-ubuntu-12.04/Gemfile +0 -2
- data/packaging/debian/docker_images/testbox-ubuntu-12.04/Gemfile.lock +0 -23
- data/packaging/debian/docker_images/testbox-ubuntu-12.04/install.sh +0 -69
- data/packaging/debian/docker_images/testbox-ubuntu-14.04/Dockerfile +0 -3
- data/packaging/debian/docker_images/testbox-ubuntu-14.04/Gemfile +0 -2
- data/packaging/debian/docker_images/testbox-ubuntu-14.04/Gemfile.lock +0 -23
- data/packaging/debian/docker_images/testbox-ubuntu-14.04/install.sh +0 -69
- data/packaging/debian/docker_images/testbox-ubuntu-15.04/Dockerfile +0 -3
- data/packaging/debian/docker_images/testbox-ubuntu-15.04/Gemfile +0 -2
- data/packaging/debian/docker_images/testbox-ubuntu-15.04/Gemfile.lock +0 -23
- data/packaging/debian/docker_images/testbox-ubuntu-15.04/install.sh +0 -69
- data/packaging/debian/docker_images/testbox-ubuntu-15.10/Dockerfile +0 -3
- data/packaging/debian/docker_images/testbox-ubuntu-15.10/Gemfile +0 -2
- data/packaging/debian/docker_images/testbox-ubuntu-15.10/Gemfile.lock +0 -23
- data/packaging/debian/docker_images/testbox-ubuntu-15.10/install.sh +0 -69
- data/packaging/debian/internal/build/Rakefile +0 -235
- data/packaging/debian/internal/build/build-passenger-orig-tarball.sh +0 -76
- data/packaging/debian/internal/build/build-source-package.rb +0 -121
- data/packaging/debian/internal/build/download-nginx-orig-tarball.sh +0 -17
- data/packaging/debian/internal/build/rakefile_support.rb +0 -96
- data/packaging/debian/internal/build/setup-environment-essentials.sh +0 -15
- data/packaging/debian/internal/build/setup-environment.sh +0 -29
- data/packaging/debian/internal/lib/distro_info.rb +0 -82
- data/packaging/debian/internal/lib/distro_info.sh +0 -303
- data/packaging/debian/internal/lib/distro_info.sh.erb +0 -65
- data/packaging/debian/internal/lib/library.sh +0 -83
- data/packaging/debian/internal/lib/preprocessor.rb +0 -173
- data/packaging/debian/internal/lib/tracking.rb +0 -95
- data/packaging/debian/internal/lib/tracking_category.rb +0 -45
- data/packaging/debian/internal/lib/tracking_database.rb +0 -132
- data/packaging/debian/internal/lib/tracking_task.rb +0 -148
- data/packaging/debian/internal/lib/utils.rb +0 -78
- data/packaging/debian/internal/publish/Rakefile +0 -97
- data/packaging/debian/internal/publish/oss-binaries.phusionpassenger.com-fingerprint.txt +0 -1
- data/packaging/debian/internal/publish/packagecloud_fingerprint.txt +0 -1
- data/packaging/debian/internal/publish/passenger_website_fingerprint.txt +0 -1
- data/packaging/debian/internal/publish/preinit.sh +0 -7
- data/packaging/debian/internal/publish/rakefile_support.rb +0 -183
- data/packaging/debian/internal/scripts/gpg_noninteractive/gpg +0 -11
- data/packaging/debian/internal/scripts/initccache.sh +0 -35
- data/packaging/debian/internal/scripts/inituidgid.sh +0 -19
- data/packaging/debian/internal/scripts/my_init +0 -340
- data/packaging/debian/internal/scripts/pin_certificates +0 -34
- data/packaging/debian/internal/scripts/regen_distro_info_script.sh +0 -3
- data/packaging/debian/internal/scripts/setup-vagrant.sh +0 -12
- data/packaging/debian/internal/scripts/setuser +0 -31
- data/packaging/debian/internal/shell/initpbuilder.sh +0 -3
- data/packaging/debian/internal/shell/preinit.sh +0 -28
- data/packaging/debian/internal/shell/sudoers.conf +0 -1
- data/packaging/debian/internal/test/apache/apache-24.conf +0 -5
- data/packaging/debian/internal/test/apache/apache-pre-24.conf +0 -4
- data/packaging/debian/internal/test/apache/vhost.conf +0 -17
- data/packaging/debian/internal/test/misc/config.json +0 -15
- data/packaging/debian/internal/test/misc/hosts.conf +0 -4
- data/packaging/debian/internal/test/misc/init.sh +0 -25
- data/packaging/debian/internal/test/misc/nodejs_test_app.js +0 -6
- data/packaging/debian/internal/test/misc/python_test_app.py +0 -3
- data/packaging/debian/internal/test/misc/ruby_test_app.rb +0 -5
- data/packaging/debian/internal/test/misc/test_support.rb +0 -61
- data/packaging/debian/internal/test/nginx/vhost.conf +0 -23
- data/packaging/debian/internal/test/system_web_server_test.rb +0 -126
- data/packaging/debian/internal/test/test.sh +0 -141
- data/packaging/debian/jenkins/publish/clear_caches.rb +0 -48
- data/packaging/debian/jenkins/publish/publish.sh +0 -69
- data/packaging/debian/jenkins/test/test.sh +0 -63
- data/packaging/debian/passenger_apt_automation.sublime-project +0 -14
- data/packaging/debian/publish +0 -172
- data/packaging/debian/shell +0 -116
- data/packaging/debian/test +0 -142
- data/packaging/rpm/passenger_spec/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -45
- data/test/cxx/Base64Test.cpp +0 -50
- data/test/cxx/FileBackedPipeTest.cpp +0 -626
- data/test/cxx/HttpHeaderBuffererTest.cpp +0 -257
- data/test/cxx/ScgiRequestParserTest.cpp +0 -423
- data/test/cxx/ServerInstanceDirTest.cpp +0 -175
- data/test/ruby/admin_tools_spec.rb +0 -360
- data/test/ruby/classic_rails/loader_spec.rb +0 -46
- data/test/ruby/classic_rails/preloader_spec.rb +0 -52
- data/test/ruby/standalone/runtime_locator_spec.rb +0 -214
- data/test/stub/rails2.3/Rakefile +0 -10
- data/test/stub/rails2.3/app/controllers/application_controller.rb +0 -10
- data/test/stub/rails2.3/app/controllers/bar_controller_1.rb +0 -5
- data/test/stub/rails2.3/app/controllers/bar_controller_2.rb +0 -5
- data/test/stub/rails2.3/app/controllers/foo_controller.rb +0 -21
- data/test/stub/rails2.3/app/helpers/application_helper.rb +0 -3
- data/test/stub/rails2.3/app/helpers/bar_helper.rb +0 -2
- data/test/stub/rails2.3/app/helpers/foo_helper.rb +0 -2
- data/test/stub/rails2.3/config/boot.rb +0 -110
- data/test/stub/rails2.3/config/database.yml +0 -19
- data/test/stub/rails2.3/config/environment.rb +0 -62
- data/test/stub/rails2.3/config/environments/development.rb +0 -17
- data/test/stub/rails2.3/config/environments/production.rb +0 -18
- data/test/stub/rails2.3/config/environments/staging.rb +0 -18
- data/test/stub/rails2.3/config/initializers/inflections.rb +0 -10
- data/test/stub/rails2.3/config/initializers/mime_types.rb +0 -5
- data/test/stub/rails2.3/config/routes.rb +0 -35
- data/test/stub/rails2.3/log/.gitignore +0 -1
- data/test/stub/rails2.3/public/.gitignore +0 -1
- data/test/stub/rails2.3/script/about +0 -3
- data/test/stub/rails2.3/script/console +0 -3
- data/test/stub/rails2.3/script/dbconsole +0 -3
- data/test/stub/rails2.3/script/destroy +0 -3
- data/test/stub/rails2.3/script/generate +0 -3
- data/test/stub/rails2.3/script/performance/benchmarker +0 -3
- data/test/stub/rails2.3/script/performance/profiler +0 -3
- data/test/stub/rails2.3/script/performance/request +0 -3
- data/test/stub/rails2.3/script/plugin +0 -3
- data/test/stub/rails2.3/script/process/inspector +0 -3
- data/test/stub/rails2.3/script/process/reaper +0 -3
- data/test/stub/rails2.3/script/process/spawner +0 -3
- data/test/stub/rails2.3/script/runner +0 -3
- data/test/stub/rails2.3/script/server +0 -3
- data/test/stub/rails2.3/tmp/cache/.gitignore +0 -1
- data/test/stub/rails2.3/tmp/pids/.gitignore +0 -1
- data/test/stub/rails2.3/tmp/sessions/.gitignore +0 -1
- data/test/stub/rails2.3/tmp/sockets/.gitignore +0 -1
@@ -0,0 +1,311 @@
|
|
1
|
+
/*
|
2
|
+
* Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
+
* Copyright (c) 2010-2014 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
|
+
#ifndef _PASSENGER_SERVER_OPTION_PARSER_H_
|
26
|
+
#define _PASSENGER_SERVER_OPTION_PARSER_H_
|
27
|
+
|
28
|
+
#include <boost/thread.hpp>
|
29
|
+
#include <cstdio>
|
30
|
+
#include <cstdlib>
|
31
|
+
#include <Constants.h>
|
32
|
+
#include <Utils.h>
|
33
|
+
#include <Utils/VariantMap.h>
|
34
|
+
#include <Utils/OptionParsing.h>
|
35
|
+
#include <Utils/StrIntUtils.h>
|
36
|
+
|
37
|
+
namespace Passenger {
|
38
|
+
|
39
|
+
using namespace std;
|
40
|
+
|
41
|
+
|
42
|
+
inline void
|
43
|
+
serverUsage() {
|
44
|
+
printf("Usage: " AGENT_EXE " server <OPTIONS...> [APP DIRECTORY]\n");
|
45
|
+
printf("Runs the " PROGRAM_NAME " standalone HTTP server agent.\n");
|
46
|
+
printf("\n");
|
47
|
+
printf("The server starts in single-app mode, unless --multi-app is specified. When\n");
|
48
|
+
printf("in single-app mode, it serves the app at the current working directory, or the\n");
|
49
|
+
printf("app specified by APP DIRECTORY.\n");
|
50
|
+
printf("\n");
|
51
|
+
printf("Required options:\n");
|
52
|
+
printf(" --passenger-root PATH The location to the " PROGRAM_NAME " source\n");
|
53
|
+
printf(" directory\n");
|
54
|
+
printf("\n");
|
55
|
+
printf("Socket options (optional):\n");
|
56
|
+
printf(" -l, --listen ADDRESS Listen on the given address. The address must be\n");
|
57
|
+
printf(" formatted as tcp://IP:PORT for TCP sockets, or\n");
|
58
|
+
printf(" unix:PATH for Unix domain sockets. You can specify\n");
|
59
|
+
printf(" this option multiple times (up to %u times) to\n",
|
60
|
+
SERVER_KIT_MAX_SERVER_ENDPOINTS);
|
61
|
+
printf(" listen on multiple addresses. Default:\n");
|
62
|
+
printf(" " DEFAULT_HTTP_SERVER_LISTEN_ADDRESS "\n");
|
63
|
+
printf(" --admin-listen ADDRESS\n");
|
64
|
+
printf(" Listen on the given address for admin commands.\n");
|
65
|
+
printf(" The same syntax and limitations as with --listen\n");
|
66
|
+
printf(" are applicable\n");
|
67
|
+
printf("\n");
|
68
|
+
printf("Daemon options (optional):\n");
|
69
|
+
printf(" --pid-file PATH Store the server's PID in the given file. The file\n");
|
70
|
+
printf(" is deleted on exit\n");
|
71
|
+
printf("\n");
|
72
|
+
printf("Security options (optional):\n");
|
73
|
+
printf(" --multi-app-password-file PATH\n");
|
74
|
+
printf(" Password-protect access to the HTTP server\n");
|
75
|
+
printf(" (multi-app mode only)\n");
|
76
|
+
printf(" --authorize [LEVEL]:USERNAME:PASSWORDFILE\n");
|
77
|
+
printf(" Enables authentication on the admin server, through\n");
|
78
|
+
printf(" the given admin account. LEVEL indicates the\n");
|
79
|
+
printf(" privilege level (see below). PASSWORDFILE must\n");
|
80
|
+
printf(" point to a file containing the password\n");
|
81
|
+
printf("\n");
|
82
|
+
printf("Application serving options (optional):\n");
|
83
|
+
printf(" -e, --environment NAME Default framework environment name to use.\n");
|
84
|
+
printf(" Default: " DEFAULT_APP_ENV "\n");
|
85
|
+
printf(" --app-type TYPE The type of application you want to serve\n");
|
86
|
+
printf(" (single-app mode only)\n");
|
87
|
+
printf(" --startup-file PATH The path of the app's startup file, relative to\n");
|
88
|
+
printf(" the app root directory (single-app mode only)\n");
|
89
|
+
printf(" --spawn-method NAME Spawn method to use. Can either be 'smart' or\n");
|
90
|
+
printf(" 'direct'. Default: %s\n", DEFAULT_SPAWN_METHOD);
|
91
|
+
printf(" --load-shell-envvars Load shell startup files before loading application\n");
|
92
|
+
printf(" --concurrency-model The concurrency model to use for the app, either\n");
|
93
|
+
printf(" 'process' or 'thread' (Enterprise only).\n");
|
94
|
+
printf(" Default: " DEFAULT_CONCURRENCY_MODEL "\n");
|
95
|
+
printf(" --app-thread-count The number of application threads to use when using\n");
|
96
|
+
printf(" the 'thread' concurrency model (Enterprise only).\n");
|
97
|
+
printf(" Default: %d\n", DEFAULT_APP_THREAD_COUNT);
|
98
|
+
printf("\n");
|
99
|
+
printf(" --multi-app Enable multi-app mode\n");
|
100
|
+
printf("\n");
|
101
|
+
printf(" --force-friendly-error-pages\n");
|
102
|
+
printf(" Force friendly error pages to be always on\n");
|
103
|
+
printf(" --disable-friendly-error-pages\n");
|
104
|
+
printf(" Force friendly error pages to be always off\n");
|
105
|
+
printf(" --disable-turbocaching\n");
|
106
|
+
printf(" Disable turbocaching\n");
|
107
|
+
printf("\n");
|
108
|
+
printf(" --ruby PATH Default Ruby interpreter to use.\n");
|
109
|
+
printf("\n");
|
110
|
+
printf(" --rolling-restarts Enable rolling restarts (Enterprise only)\n");
|
111
|
+
printf("\n");
|
112
|
+
printf("Process management options (optional):\n");
|
113
|
+
printf(" --max-pool-size N Maximum number of application processes.\n");
|
114
|
+
printf(" Default: %d\n", DEFAULT_MAX_POOL_SIZE);
|
115
|
+
printf(" --pool-idle-time SECS\n");
|
116
|
+
printf(" Maximum number of seconds an application process\n");
|
117
|
+
printf(" may be idle. Default: %d\n", DEFAULT_POOL_IDLE_TIME);
|
118
|
+
printf(" --min-instances N Minimum number of application processes. Default: 1\n");
|
119
|
+
printf("\n");
|
120
|
+
printf("Other options (optional):\n");
|
121
|
+
printf(" --log-file PATH Log to the given file.\n");
|
122
|
+
printf(" --log-level LEVEL Logging level. Default: %d\n", DEFAULT_LOG_LEVEL);
|
123
|
+
printf(" --stat-throttle-rate SECONDS\n");
|
124
|
+
printf(" Throttle filesystem restart.txt checks to at most\n");
|
125
|
+
printf(" once per given seconds. Default: %d\n", DEFAULT_STAT_THROTTLE_RATE);
|
126
|
+
printf(" --no-show-version-in-header\n");
|
127
|
+
printf(" Do not show " PROGRAM_NAME " version number in\n");
|
128
|
+
printf(" HTTP headers.\n");
|
129
|
+
printf(" --data-buffer-dir PATH\n");
|
130
|
+
printf(" Directory to store data buffers in. Default:\n");
|
131
|
+
printf(" %s\n", getSystemTempDir());
|
132
|
+
printf(" --no-graceful-exit When exiting, exit immediately instead of waiting\n");
|
133
|
+
printf(" for all connections to terminate\n");
|
134
|
+
printf(" --benchmark MODE Enable benchmark mode. Available modes:\n");
|
135
|
+
printf(" after_accept,before_checkout,after_checkout,\n");
|
136
|
+
printf(" response_begin\n");
|
137
|
+
printf(" --disable-selfchecks Disable various self-checks. This improves\n");
|
138
|
+
printf(" performance, but might delay finding bugs in\n");
|
139
|
+
printf(" " PROGRAM_NAME "\n");
|
140
|
+
printf(" --threads NUMBER Number of threads to use for request handling.\n");
|
141
|
+
printf(" Default: number of CPU cores (%d)\n",
|
142
|
+
boost::thread::hardware_concurrency());
|
143
|
+
printf(" --cpu-affine Enable per-thread CPU affinity (Linux only)\n");
|
144
|
+
printf(" -h, --help Show this help\n");
|
145
|
+
printf("\n");
|
146
|
+
printf("Admin account privilege levels (ordered from most to least privileges):\n");
|
147
|
+
printf(" readonly Read-only access\n");
|
148
|
+
printf(" full Full access (default)\n");
|
149
|
+
}
|
150
|
+
|
151
|
+
inline bool
|
152
|
+
parseServerOption(int argc, const char *argv[], int &i, VariantMap &options) {
|
153
|
+
OptionParser p(serverUsage);
|
154
|
+
|
155
|
+
if (p.isValueFlag(argc, i, argv[i], '\0', "--passenger-root")) {
|
156
|
+
options.set("passenger_root", argv[i + 1]);
|
157
|
+
i += 2;
|
158
|
+
} else if (p.isValueFlag(argc, i, argv[i], 'l', "--listen")) {
|
159
|
+
if (getSocketAddressType(argv[i + 1]) != SAT_UNKNOWN) {
|
160
|
+
vector<string> addresses = options.getStrSet("server_addresses", false);
|
161
|
+
if (addresses.size() == SERVER_KIT_MAX_SERVER_ENDPOINTS) {
|
162
|
+
fprintf(stderr, "ERROR: you may specify up to %u --listen addresses.\n",
|
163
|
+
SERVER_KIT_MAX_SERVER_ENDPOINTS);
|
164
|
+
exit(1);
|
165
|
+
}
|
166
|
+
addresses.push_back(argv[i + 1]);
|
167
|
+
options.setStrSet("server_addresses", addresses);
|
168
|
+
i += 2;
|
169
|
+
} else {
|
170
|
+
fprintf(stderr, "ERROR: invalid address format for --listen. The address "
|
171
|
+
"must be formatted as tcp://IP:PORT for TCP sockets, or unix:PATH "
|
172
|
+
"for Unix domain sockets.\n");
|
173
|
+
exit(1);
|
174
|
+
}
|
175
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--admin-listen")) {
|
176
|
+
if (getSocketAddressType(argv[i + 1]) != SAT_UNKNOWN) {
|
177
|
+
vector<string> addresses = options.getStrSet("server_admin_addresses",
|
178
|
+
false);
|
179
|
+
if (addresses.size() == SERVER_KIT_MAX_SERVER_ENDPOINTS) {
|
180
|
+
fprintf(stderr, "ERROR: you may specify up to %u --admin-listen addresses.\n",
|
181
|
+
SERVER_KIT_MAX_SERVER_ENDPOINTS);
|
182
|
+
exit(1);
|
183
|
+
}
|
184
|
+
addresses.push_back(argv[i + 1]);
|
185
|
+
options.setStrSet("server_admin_addresses", addresses);
|
186
|
+
i += 2;
|
187
|
+
} else {
|
188
|
+
fprintf(stderr, "ERROR: invalid address format for --admin-listen. The address "
|
189
|
+
"must be formatted as tcp://IP:PORT for TCP sockets, or unix:PATH "
|
190
|
+
"for Unix domain sockets.\n");
|
191
|
+
exit(1);
|
192
|
+
}
|
193
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--pid-file")) {
|
194
|
+
options.set("server_pid_file", argv[i + 1]);
|
195
|
+
i += 2;
|
196
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--authorize")) {
|
197
|
+
vector<string> args;
|
198
|
+
vector<string> authorizations = options.getStrSet("server_authorizations",
|
199
|
+
false);
|
200
|
+
|
201
|
+
split(argv[i + 1], ':', args);
|
202
|
+
if (args.size() < 2 || args.size() > 3) {
|
203
|
+
fprintf(stderr, "ERROR: invalid format for --authorize. The syntax "
|
204
|
+
"is \"[LEVEL:]USERNAME:PASSWORDFILE\".\n");
|
205
|
+
exit(1);
|
206
|
+
}
|
207
|
+
|
208
|
+
authorizations.push_back(argv[i + 1]);
|
209
|
+
options.setStrSet("server_authorizations", authorizations);
|
210
|
+
i += 2;
|
211
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--max-pool-size")) {
|
212
|
+
options.setInt("max_pool_size", atoi(argv[i + 1]));
|
213
|
+
i += 2;
|
214
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--pool-idle-time")) {
|
215
|
+
options.setInt("pool_idle_time", atoi(argv[i + 1]));
|
216
|
+
i += 2;
|
217
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--min-instances")) {
|
218
|
+
options.setInt("min_instances", atoi(argv[i + 1]));
|
219
|
+
i += 2;
|
220
|
+
} else if (p.isValueFlag(argc, i, argv[i], 'e', "--environment")) {
|
221
|
+
options.set("environment", argv[i + 1]);
|
222
|
+
i += 2;
|
223
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--app-type")) {
|
224
|
+
options.set("app_type", argv[i + 1]);
|
225
|
+
i += 2;
|
226
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--startup-file")) {
|
227
|
+
options.set("startup_file", argv[i + 1]);
|
228
|
+
i += 2;
|
229
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--spawn-method")) {
|
230
|
+
options.set("spawn_method", argv[i + 1]);
|
231
|
+
i += 2;
|
232
|
+
} else if (p.isFlag(argv[i], '\0', "--load-shell-envvars")) {
|
233
|
+
options.setBool("load_shell_envvars", true);
|
234
|
+
i++;
|
235
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--concurrency-model")) {
|
236
|
+
options.set("concurrency_model", argv[i + 1]);
|
237
|
+
i += 2;
|
238
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--app-thread-count")) {
|
239
|
+
options.setInt("app_thread_count", atoi(argv[i + 1]));
|
240
|
+
i += 2;
|
241
|
+
} else if (p.isFlag(argv[i], '\0', "--multi-app")) {
|
242
|
+
options.setBool("multi_app", true);
|
243
|
+
i++;
|
244
|
+
} else if (p.isFlag(argv[i], '\0', "--force-friendly-error-pages")) {
|
245
|
+
options.set("friendly_error_pages", "true");
|
246
|
+
i++;
|
247
|
+
} else if (p.isFlag(argv[i], '\0', "--disable-friendly-error-pages")) {
|
248
|
+
options.set("friendly_error_pages", "false");
|
249
|
+
i++;
|
250
|
+
} else if (p.isFlag(argv[i], '\0', "--disable-turbocaching")) {
|
251
|
+
options.setBool("turbocaching", false);
|
252
|
+
i++;
|
253
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--ruby")) {
|
254
|
+
options.set("default_ruby", argv[i + 1]);
|
255
|
+
i += 2;
|
256
|
+
} else if (p.isFlag(argv[i], '\0', "--rolling-restarts")) {
|
257
|
+
options.setBool("rolling_restarts", true);
|
258
|
+
i++;
|
259
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--log-level")) {
|
260
|
+
// We do not set log_level because, when this function is called from
|
261
|
+
// the Watchdog, we don't want to affect the Watchdog's own log level.
|
262
|
+
options.setInt("server_log_level", atoi(argv[i + 1]));
|
263
|
+
i += 2;
|
264
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--log-file")) {
|
265
|
+
// We do not set debug_log_file because, when this function is called from
|
266
|
+
// the Watchdog, we don't want to affect the Watchdog's own log file.
|
267
|
+
options.set("server_log_file", argv[i + 1]);
|
268
|
+
i += 2;
|
269
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--stat-throttle-rate")) {
|
270
|
+
options.setInt("stat_throttle_rate", atoi(argv[i + 1]));
|
271
|
+
i += 2;
|
272
|
+
} else if (p.isFlag(argv[i], '\0', "--no-show-version-in-header")) {
|
273
|
+
options.setBool("show_version_in_header", false);
|
274
|
+
i++;
|
275
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--data-buffer-dir")) {
|
276
|
+
options.setInt("data_buffer_dir", atoi(argv[i + 1]));
|
277
|
+
i += 2;
|
278
|
+
} else if (p.isFlag(argv[i], '\0', "--no-graceful-exit")) {
|
279
|
+
options.setBool("server_graceful_exit", false);
|
280
|
+
i++;
|
281
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--benchmark")) {
|
282
|
+
options.set("benchmark_mode", argv[i + 1]);
|
283
|
+
i += 2;
|
284
|
+
} else if (p.isFlag(argv[i], '\0', "--disable-selfchecks")) {
|
285
|
+
options.setBool("selfchecks", false);
|
286
|
+
i++;
|
287
|
+
} else if (p.isValueFlag(argc, i, argv[i], '\0', "--threads")) {
|
288
|
+
options.setInt("server_threads", atoi(argv[i + 1]));
|
289
|
+
i += 2;
|
290
|
+
} else if (p.isFlag(argv[i], '\0', "--cpu-affine")) {
|
291
|
+
options.setBool("server_cpu_affine", true);
|
292
|
+
i++;
|
293
|
+
} else if (!startsWith(argv[i], "-")) {
|
294
|
+
if (!options.has("app_root")) {
|
295
|
+
options.set("app_root", argv[i]);
|
296
|
+
i++;
|
297
|
+
} else {
|
298
|
+
fprintf(stderr, "ERROR: you may not pass multiple application directories. "
|
299
|
+
"Please type '%s server --help' for usage.\n", argv[0]);
|
300
|
+
exit(1);
|
301
|
+
}
|
302
|
+
} else {
|
303
|
+
return false;
|
304
|
+
}
|
305
|
+
return true;
|
306
|
+
}
|
307
|
+
|
308
|
+
|
309
|
+
} // namespace Passenger
|
310
|
+
|
311
|
+
#endif /* _PASSENGER_SERVER_OPTION_PARSER_H_ */
|
@@ -109,12 +109,14 @@
|
|
109
109
|
#ifndef _PASSENGER_REQUEST_HANDLER_H_
|
110
110
|
#define _PASSENGER_REQUEST_HANDLER_H_
|
111
111
|
|
112
|
+
//#define DEBUG_RH_EVENT_LOOP_BLOCKING
|
113
|
+
|
112
114
|
#include <boost/shared_ptr.hpp>
|
113
|
-
#include <boost/weak_ptr.hpp>
|
114
115
|
#include <boost/make_shared.hpp>
|
115
|
-
#include <boost/regex.hpp>
|
116
116
|
#include <boost/cstdint.hpp>
|
117
|
+
#include <oxt/macros.hpp>
|
117
118
|
#include <ev++.h>
|
119
|
+
#include <ostream>
|
118
120
|
|
119
121
|
#if defined(__GLIBCXX__) || defined(__APPLE__)
|
120
122
|
#include <cxxabi.h>
|
@@ -122,32 +124,34 @@
|
|
122
124
|
#endif
|
123
125
|
|
124
126
|
#include <sys/types.h>
|
125
|
-
#include <
|
126
|
-
#include <sys/un.h>
|
127
|
+
#include <sys/uio.h>
|
127
128
|
#include <utility>
|
128
129
|
#include <typeinfo>
|
130
|
+
#include <cstdio>
|
129
131
|
#include <cassert>
|
130
132
|
#include <cctype>
|
131
133
|
|
132
134
|
#include <Logging.h>
|
133
|
-
#include <EventedBufferedInput.h>
|
134
135
|
#include <MessageReadersWriters.h>
|
135
136
|
#include <Constants.h>
|
136
|
-
#include <
|
137
|
-
#include <
|
138
|
-
#include <
|
139
|
-
#include <
|
137
|
+
#include <ServerKit/Errors.h>
|
138
|
+
#include <ServerKit/HttpServer.h>
|
139
|
+
#include <ServerKit/HttpHeaderParser.h>
|
140
|
+
#include <MemoryKit/palloc.h>
|
141
|
+
#include <DataStructures/LString.h>
|
142
|
+
#include <DataStructures/StringKeyTable.h>
|
140
143
|
#include <ApplicationPool2/ErrorRenderer.h>
|
144
|
+
#include <StaticString.h>
|
145
|
+
#include <Utils.h>
|
141
146
|
#include <Utils/StrIntUtils.h>
|
142
147
|
#include <Utils/IOUtils.h>
|
143
|
-
#include <Utils/
|
148
|
+
#include <Utils/JsonUtils.h>
|
144
149
|
#include <Utils/HttpConstants.h>
|
145
|
-
#include <Utils/
|
150
|
+
#include <Utils/VariantMap.h>
|
146
151
|
#include <Utils/Timer.h>
|
147
|
-
#include <
|
148
|
-
#include <agents/HelperAgent/
|
149
|
-
#include <agents/HelperAgent/
|
150
|
-
#include <agents/HelperAgent/ScgiRequestParser.h>
|
152
|
+
#include <agents/HelperAgent/RequestHandler/Client.h>
|
153
|
+
#include <agents/HelperAgent/RequestHandler/AppResponse.h>
|
154
|
+
#include <agents/HelperAgent/RequestHandler/TurboCaching.h>
|
151
155
|
|
152
156
|
namespace Passenger {
|
153
157
|
|
@@ -156,2595 +160,358 @@ using namespace boost;
|
|
156
160
|
using namespace oxt;
|
157
161
|
using namespace ApplicationPool2;
|
158
162
|
|
159
|
-
class RequestHandler;
|
160
|
-
|
161
|
-
#define MAX_STATUS_HEADER_SIZE 64
|
162
|
-
|
163
|
-
#define RH_ERROR(client, x) P_ERROR("[Client " << client->name() << "] " << x)
|
164
|
-
#define RH_WARN(client, x) P_WARN("[Client " << client->name() << "] " << x)
|
165
|
-
#define RH_DEBUG(client, x) P_DEBUG("[Client " << client->name() << "] " << x)
|
166
|
-
#define RH_TRACE(client, level, x) P_TRACE(level, "[Client " << client->name() << "] " << x)
|
167
|
-
|
168
|
-
#define RH_LOG_EVENT(client, eventName) \
|
169
|
-
char _clientName[7 + 8]; \
|
170
|
-
snprintf(_clientName, sizeof(_clientName), "Client %d", client->fdnum); \
|
171
|
-
TRACE_POINT_WITH_DATA(_clientName); \
|
172
|
-
RH_TRACE(client, 3, "Event: " eventName)
|
173
|
-
|
174
|
-
|
175
|
-
class Client: public boost::enable_shared_from_this<Client> {
|
176
|
-
private:
|
177
|
-
struct ev_loop *getLoop() const;
|
178
|
-
const SafeLibevPtr &getSafeLibev() const;
|
179
|
-
unsigned int getConnectPasswordTimeout(const RequestHandler *handler) const;
|
180
|
-
|
181
|
-
static size_t onClientInputData(const EventedBufferedInputPtr &source, const StaticString &data);
|
182
|
-
static void onClientInputError(const EventedBufferedInputPtr &source, const char *message, int errnoCode);
|
183
|
-
|
184
|
-
static void onClientBodyBufferData(const FileBackedPipePtr &source,
|
185
|
-
const char *data, size_t size,
|
186
|
-
const FileBackedPipe::ConsumeCallback &callback);
|
187
|
-
static void onClientBodyBufferEnd(const FileBackedPipePtr &source);
|
188
|
-
static void onClientBodyBufferError(const FileBackedPipePtr &source, int errorCode);
|
189
|
-
static void onClientBodyBufferCommit(const FileBackedPipePtr &source);
|
190
|
-
|
191
|
-
static void onClientOutputPipeData(const FileBackedPipePtr &source,
|
192
|
-
const char *data, size_t size,
|
193
|
-
const FileBackedPipe::ConsumeCallback &callback);
|
194
|
-
static void onClientOutputPipeEnd(const FileBackedPipePtr &source);
|
195
|
-
static void onClientOutputPipeError(const FileBackedPipePtr &source, int errorCode);
|
196
|
-
static void onClientOutputPipeCommit(const FileBackedPipePtr &source);
|
197
|
-
|
198
|
-
void onClientOutputWritable(ev::io &io, int revents);
|
199
|
-
|
200
|
-
static size_t onAppInputData(const EventedBufferedInputPtr &source, const StaticString &data);
|
201
|
-
static void onAppInputChunk(const char *data, size_t size, void *userData);
|
202
|
-
static void onAppInputChunkEnd(void *userData);
|
203
|
-
static void onAppInputError(const EventedBufferedInputPtr &source, const char *message, int errnoCode);
|
204
|
-
|
205
|
-
void onAppOutputWritable(ev::io &io, int revents);
|
206
|
-
|
207
|
-
void onTimeout(ev::timer &timer, int revents);
|
208
|
-
|
209
|
-
|
210
|
-
static const char *boolStr(bool val) {
|
211
|
-
static const char *strs[] = { "false", "true" };
|
212
|
-
return strs[val];
|
213
|
-
}
|
214
|
-
|
215
|
-
void resetPrimitiveFields() {
|
216
|
-
requestHandler = NULL;
|
217
|
-
state = DISCONNECTED;
|
218
|
-
backgroundOperations = 0;
|
219
|
-
requestBodyIsBuffered = false;
|
220
|
-
requestIsChunked = false;
|
221
|
-
freeBufferedConnectPassword();
|
222
|
-
connectedAt = 0;
|
223
|
-
requestBodyLength = 0;
|
224
|
-
requestBodyAlreadyRead = 0;
|
225
|
-
checkoutSessionAfterCommit = false;
|
226
|
-
stickySession = false;
|
227
|
-
sessionCheckedOut = false;
|
228
|
-
sessionCheckoutTry = 0;
|
229
|
-
responseHeaderSeen = false;
|
230
|
-
chunkedResponse = false;
|
231
|
-
responseContentLength = -1;
|
232
|
-
responseBodyAlreadyRead = 0;
|
233
|
-
appRoot.clear();
|
234
|
-
}
|
235
|
-
|
236
|
-
void freeScopeLogs() {
|
237
|
-
endScopeLog(&scopeLogs.requestProxying, false);
|
238
|
-
endScopeLog(&scopeLogs.getFromPool, false);
|
239
|
-
endScopeLog(&scopeLogs.bufferingRequestBody, false);
|
240
|
-
endScopeLog(&scopeLogs.requestProcessing, false);
|
241
|
-
}
|
242
|
-
|
243
|
-
public:
|
244
|
-
/** Back reference to the RequestHandler that this Client is associated with.
|
245
|
-
* NULL when this Client is not in the pool or is disconnected. */
|
246
|
-
RequestHandler *requestHandler;
|
247
|
-
/** File descriptor of the client socket. Is empty when this Client is not
|
248
|
-
* in the pool or is disconnected. */
|
249
|
-
FileDescriptor fd;
|
250
|
-
/** The last associated file descriptor number is stored here. It is not
|
251
|
-
* cleared after disassociating. Its only purpose is to make logging calls
|
252
|
-
* like RH_DEBUG() print the correct client name after disconnect() is called.
|
253
|
-
* Do not use this value for anything else as it may not refer to a valid
|
254
|
-
* file descriptor. */
|
255
|
-
int fdnum;
|
256
|
-
|
257
|
-
|
258
|
-
/***** Client <-> RequestHandler I/O channels, pipes and watchers *****/
|
259
|
-
|
260
|
-
/** Client input channel. */
|
261
|
-
EventedBufferedInputPtr clientInput;
|
262
|
-
/** If request body buffering is turned on, it will be buffered into this FileBackedPipe. */
|
263
|
-
FileBackedPipePtr clientBodyBuffer;
|
264
|
-
/** Client output pipe. */
|
265
|
-
FileBackedPipePtr clientOutputPipe;
|
266
|
-
/** Client output channel watcher. */
|
267
|
-
ev::io clientOutputWatcher;
|
268
|
-
|
269
|
-
|
270
|
-
/***** RequestHandler <-> Application I/O channels, pipes and watchers *****/
|
271
|
-
|
272
|
-
/** Application input channel. */
|
273
|
-
EventedBufferedInputPtr appInput;
|
274
|
-
string appOutputBuffer;
|
275
|
-
/** Application output channel watcher. */
|
276
|
-
ev::io appOutputWatcher;
|
277
|
-
|
278
|
-
|
279
|
-
/***** State variables *****/
|
280
|
-
|
281
|
-
enum {
|
282
|
-
BEGIN_READING_CONNECT_PASSWORD,
|
283
|
-
STILL_READING_CONNECT_PASSWORD,
|
284
|
-
READING_HEADER,
|
285
|
-
BUFFERING_REQUEST_BODY,
|
286
|
-
CHECKING_OUT_SESSION,
|
287
|
-
SENDING_HEADER_TO_APP,
|
288
|
-
FORWARDING_BODY_TO_APP,
|
289
|
-
|
290
|
-
// Special states
|
291
|
-
WRITING_SIMPLE_RESPONSE,
|
292
|
-
DISCONNECTED
|
293
|
-
} state;
|
294
|
-
|
295
|
-
/* How many background operations are currently in progress, e.g.
|
296
|
-
* an asyncGet() or bodyBuffer.add(). If the client is disconnected
|
297
|
-
* while this flag is true, then the Client object is not reassociateable
|
298
|
-
* in order to give the completion callbacks a chance to cancel properly.
|
299
|
-
*/
|
300
|
-
unsigned int backgroundOperations;
|
301
|
-
|
302
|
-
struct {
|
303
|
-
char *data;
|
304
|
-
unsigned int alreadyRead;
|
305
|
-
} bufferedConnectPassword;
|
306
|
-
|
307
|
-
// Used for enforcing the connection timeout.
|
308
|
-
ev::timer timeoutTimer;
|
309
|
-
|
310
|
-
ev_tstamp connectedAt;
|
311
|
-
/** The size of the request body. The request body is the part that comes
|
312
|
-
* after the request headers, which may be the HTTP request message body,
|
313
|
-
* but may also be any other arbitrary data that is sent over the request
|
314
|
-
* socket (e.g. WebSocket data).
|
315
|
-
*
|
316
|
-
* Possible values:
|
317
|
-
*
|
318
|
-
* -1: infinite. Should keep forwarding client body until end of stream.
|
319
|
-
* 0: no client body. Should stop after sending headers to application.
|
320
|
-
* >0: Should forward exactly this many bytes of the client body.
|
321
|
-
*/
|
322
|
-
long long requestBodyLength;
|
323
|
-
unsigned long long requestBodyAlreadyRead;
|
324
|
-
Options options;
|
325
|
-
ScgiRequestParser scgiParser;
|
326
|
-
SessionPtr session;
|
327
|
-
string appRoot;
|
328
|
-
struct {
|
329
|
-
UnionStation::ScopeLog
|
330
|
-
*requestProcessing,
|
331
|
-
*bufferingRequestBody,
|
332
|
-
*getFromPool,
|
333
|
-
*requestProxying;
|
334
|
-
} scopeLogs;
|
335
|
-
unsigned int sessionCheckoutTry;
|
336
|
-
bool requestBodyIsBuffered;
|
337
|
-
bool requestIsChunked;
|
338
|
-
bool sessionCheckedOut;
|
339
|
-
bool checkoutSessionAfterCommit;
|
340
|
-
bool stickySession;
|
341
|
-
|
342
|
-
bool responseHeaderSeen;
|
343
|
-
bool chunkedResponse;
|
344
|
-
/** The size of the response body, set based on the values of
|
345
|
-
* the Content-Length and Transfer-Encoding response headers.
|
346
|
-
* Possible values:
|
347
|
-
*
|
348
|
-
* -1: infinite. Should keep forwarding response body until end of stream.
|
349
|
-
* This is the case for WebSockets or for responses without Content-Length.
|
350
|
-
* Responses with "Transfer-Encoding: chunked" also fall under this
|
351
|
-
* category, though in this case encountering the zero-length chunk is
|
352
|
-
* treated the same as end of stream.
|
353
|
-
* 0 : no client body. Should immediately close connection after forwarding
|
354
|
-
* headers.
|
355
|
-
* >0: Should forward exactly this many bytes of the response body.
|
356
|
-
*/
|
357
|
-
long long responseContentLength;
|
358
|
-
unsigned long long responseBodyAlreadyRead;
|
359
|
-
HttpHeaderBufferer responseHeaderBufferer;
|
360
|
-
Dechunker responseDechunker;
|
361
|
-
|
362
|
-
|
363
|
-
Client() {
|
364
|
-
fdnum = -1;
|
365
|
-
|
366
|
-
clientInput = boost::make_shared< EventedBufferedInput<> >();
|
367
|
-
clientInput->onData = onClientInputData;
|
368
|
-
clientInput->onError = onClientInputError;
|
369
|
-
clientInput->userData = this;
|
370
|
-
|
371
|
-
clientBodyBuffer = boost::make_shared<FileBackedPipe>("/tmp");
|
372
|
-
clientBodyBuffer->userData = this;
|
373
|
-
clientBodyBuffer->onData = onClientBodyBufferData;
|
374
|
-
clientBodyBuffer->onEnd = onClientBodyBufferEnd;
|
375
|
-
clientBodyBuffer->onError = onClientBodyBufferError;
|
376
|
-
clientBodyBuffer->onCommit = onClientBodyBufferCommit;
|
377
|
-
|
378
|
-
clientOutputPipe = boost::make_shared<FileBackedPipe>("/tmp");
|
379
|
-
clientOutputPipe->userData = this;
|
380
|
-
clientOutputPipe->onData = onClientOutputPipeData;
|
381
|
-
clientOutputPipe->onEnd = onClientOutputPipeEnd;
|
382
|
-
clientOutputPipe->onError = onClientOutputPipeError;
|
383
|
-
clientOutputPipe->onCommit = onClientOutputPipeCommit;
|
384
|
-
|
385
|
-
clientOutputWatcher.set<Client, &Client::onClientOutputWritable>(this);
|
386
|
-
|
387
|
-
|
388
|
-
appInput = boost::make_shared< EventedBufferedInput<> >();
|
389
|
-
appInput->onData = onAppInputData;
|
390
|
-
appInput->onError = onAppInputError;
|
391
|
-
appInput->userData = this;
|
392
|
-
|
393
|
-
appOutputWatcher.set<Client, &Client::onAppOutputWritable>(this);
|
394
|
-
|
395
|
-
|
396
|
-
timeoutTimer.set<Client, &Client::onTimeout>(this);
|
397
|
-
|
398
|
-
|
399
|
-
responseDechunker.onData = onAppInputChunk;
|
400
|
-
responseDechunker.onEnd = onAppInputChunkEnd;
|
401
|
-
responseDechunker.userData = this;
|
402
|
-
|
403
|
-
|
404
|
-
bufferedConnectPassword.data = NULL;
|
405
|
-
bufferedConnectPassword.alreadyRead = 0;
|
406
|
-
memset(&scopeLogs, 0, sizeof(scopeLogs));
|
407
|
-
resetPrimitiveFields();
|
408
|
-
}
|
409
|
-
|
410
|
-
~Client() {
|
411
|
-
if (requestHandler != NULL) {
|
412
|
-
discard();
|
413
|
-
}
|
414
|
-
clientInput->userData = NULL;
|
415
|
-
clientBodyBuffer->userData = NULL;
|
416
|
-
clientOutputPipe->userData = NULL;
|
417
|
-
appInput->userData = NULL;
|
418
|
-
freeBufferedConnectPassword();
|
419
|
-
freeScopeLogs();
|
420
|
-
}
|
421
|
-
|
422
|
-
void associate(RequestHandler *handler, const FileDescriptor &_fd) {
|
423
|
-
assert(requestHandler == NULL);
|
424
|
-
requestHandler = handler;
|
425
|
-
fd = _fd;
|
426
|
-
fdnum = _fd;
|
427
|
-
state = BEGIN_READING_CONNECT_PASSWORD;
|
428
|
-
connectedAt = ev_time();
|
429
|
-
|
430
|
-
clientInput->reset(getSafeLibev().get(), _fd);
|
431
|
-
clientInput->start();
|
432
|
-
clientBodyBuffer->reset(getSafeLibev());
|
433
|
-
clientOutputPipe->reset(getSafeLibev());
|
434
|
-
clientOutputPipe->start();
|
435
|
-
clientOutputWatcher.set(getLoop());
|
436
|
-
clientOutputWatcher.set(_fd, ev::WRITE);
|
437
|
-
|
438
|
-
// appOutputWatcher is initialized in initiateSession.
|
439
|
-
|
440
|
-
timeoutTimer.set(getLoop());
|
441
|
-
timeoutTimer.start(getConnectPasswordTimeout(handler) / 1000.0, 0.0);
|
442
|
-
}
|
443
|
-
|
444
|
-
void disassociate() {
|
445
|
-
assert(requestHandler != NULL);
|
446
|
-
resetPrimitiveFields();
|
447
|
-
fd = FileDescriptor();
|
448
|
-
|
449
|
-
clientInput->reset(NULL, FileDescriptor());
|
450
|
-
clientBodyBuffer->reset();
|
451
|
-
clientOutputPipe->reset();
|
452
|
-
clientOutputWatcher.stop();
|
453
|
-
|
454
|
-
appInput->reset(NULL, FileDescriptor());
|
455
|
-
appOutputBuffer.resize(0);
|
456
|
-
appOutputWatcher.stop();
|
457
|
-
|
458
|
-
timeoutTimer.stop();
|
459
|
-
scgiParser.reset();
|
460
|
-
session.reset();
|
461
|
-
responseHeaderBufferer.reset();
|
462
|
-
responseDechunker.reset();
|
463
|
-
freeScopeLogs();
|
464
|
-
}
|
465
|
-
|
466
|
-
void discard() {
|
467
|
-
assert(requestHandler != NULL);
|
468
|
-
resetPrimitiveFields();
|
469
|
-
fd = FileDescriptor();
|
470
|
-
|
471
|
-
clientInput->stop();
|
472
|
-
clientBodyBuffer->reset();
|
473
|
-
clientOutputPipe->reset();
|
474
|
-
clientOutputWatcher.stop();
|
475
|
-
|
476
|
-
appInput->stop();
|
477
|
-
appOutputWatcher.stop();
|
478
|
-
|
479
|
-
timeoutTimer.stop();
|
480
|
-
|
481
|
-
freeScopeLogs();
|
482
|
-
|
483
|
-
requestHandler = NULL;
|
484
|
-
}
|
485
|
-
|
486
|
-
bool reassociateable() const {
|
487
|
-
return requestHandler == NULL
|
488
|
-
&& backgroundOperations == 0
|
489
|
-
&& clientInput->resetable()
|
490
|
-
&& clientBodyBuffer->resetable()
|
491
|
-
&& clientOutputPipe->resetable()
|
492
|
-
&& appInput->resetable();
|
493
|
-
}
|
494
|
-
|
495
|
-
string name() const {
|
496
|
-
if (fdnum == -1) {
|
497
|
-
return "(null)";
|
498
|
-
} else {
|
499
|
-
return toString(fdnum);
|
500
|
-
}
|
501
|
-
}
|
502
|
-
|
503
|
-
bool connected() const {
|
504
|
-
return requestHandler != NULL;
|
505
|
-
}
|
506
|
-
|
507
|
-
const char *getStateName() const {
|
508
|
-
switch (state) {
|
509
|
-
case BEGIN_READING_CONNECT_PASSWORD:
|
510
|
-
return "BEGIN_READING_CONNECT_PASSWORD";
|
511
|
-
case STILL_READING_CONNECT_PASSWORD:
|
512
|
-
return "STILL_READING_CONNECT_PASSWORD";
|
513
|
-
case READING_HEADER:
|
514
|
-
return "READING_HEADER";
|
515
|
-
case BUFFERING_REQUEST_BODY:
|
516
|
-
return "BUFFERING_REQUEST_BODY";
|
517
|
-
case CHECKING_OUT_SESSION:
|
518
|
-
return "CHECKING_OUT_SESSION";
|
519
|
-
case SENDING_HEADER_TO_APP:
|
520
|
-
return "SENDING_HEADER_TO_APP";
|
521
|
-
case FORWARDING_BODY_TO_APP:
|
522
|
-
return "FORWARDING_BODY_TO_APP";
|
523
|
-
case WRITING_SIMPLE_RESPONSE:
|
524
|
-
return "WRITING_SIMPLE_RESPONSE";
|
525
|
-
case DISCONNECTED:
|
526
|
-
return "DISCONNECTED";
|
527
|
-
default:
|
528
|
-
return "UNKNOWN";
|
529
|
-
}
|
530
|
-
}
|
531
|
-
|
532
|
-
void freeBufferedConnectPassword() {
|
533
|
-
if (bufferedConnectPassword.data != NULL) {
|
534
|
-
free(bufferedConnectPassword.data);
|
535
|
-
bufferedConnectPassword.data = NULL;
|
536
|
-
bufferedConnectPassword.alreadyRead = 0;
|
537
|
-
}
|
538
|
-
}
|
539
|
-
|
540
|
-
/**
|
541
|
-
* Checks whether we should half-close the application socket after forwarding
|
542
|
-
* the request. HTTP does not formally support half-closing, and Node.js treats a
|
543
|
-
* half-close as a full close, so we only half-close session sockets, not
|
544
|
-
* HTTP sockets.
|
545
|
-
*/
|
546
|
-
bool shouldHalfCloseWrite() const {
|
547
|
-
return session->getProtocol() == "session";
|
548
|
-
}
|
549
|
-
|
550
|
-
bool useUnionStation() const {
|
551
|
-
return options.transaction != NULL;
|
552
|
-
}
|
553
|
-
|
554
|
-
UnionStation::TransactionPtr getUnionStationTransaction() const {
|
555
|
-
return options.transaction;
|
556
|
-
}
|
557
|
-
|
558
|
-
void beginScopeLog(UnionStation::ScopeLog **scopeLog, const char *name) {
|
559
|
-
if (options.transaction != NULL) {
|
560
|
-
*scopeLog = new UnionStation::ScopeLog(options.transaction, name);
|
561
|
-
}
|
562
|
-
}
|
563
|
-
|
564
|
-
void endScopeLog(UnionStation::ScopeLog **scopeLog, bool success = true) {
|
565
|
-
if (success && *scopeLog != NULL) {
|
566
|
-
(*scopeLog)->success();
|
567
|
-
}
|
568
|
-
delete *scopeLog;
|
569
|
-
*scopeLog = NULL;
|
570
|
-
}
|
571
|
-
|
572
|
-
void logMessage(const StaticString &message) {
|
573
|
-
options.transaction->message(message);
|
574
|
-
}
|
575
|
-
|
576
|
-
void verifyInvariants() const {
|
577
|
-
assert((requestHandler == NULL) == (fd == -1));
|
578
|
-
assert((requestHandler == NULL) == (state == DISCONNECTED));
|
579
|
-
}
|
580
|
-
|
581
|
-
template<typename Stream>
|
582
|
-
void inspect(Stream &stream) const {
|
583
|
-
const char *indent = " ";
|
584
|
-
time_t the_time;
|
585
|
-
struct tm the_tm;
|
586
|
-
char timestr[60];
|
587
|
-
|
588
|
-
the_time = (time_t) connectedAt;
|
589
|
-
localtime_r(&the_time, &the_tm);
|
590
|
-
strftime(timestr, sizeof(timestr) - 1, "%F %H:%M:%S", &the_tm);
|
591
|
-
|
592
|
-
stream << indent << "host = " << (scgiParser.getHeader("HTTP_HOST").empty() ? "(empty)" : scgiParser.getHeader("HTTP_HOST")) << "\n";
|
593
|
-
stream << indent << "uri = " << (scgiParser.getHeader("REQUEST_URI").empty() ? "(empty)" : scgiParser.getHeader("REQUEST_URI")) << "\n";
|
594
|
-
stream << indent << "connected at = " << timestr << " (" << (unsigned long long) (ev_time() - connectedAt) << " sec ago)\n";
|
595
|
-
stream << indent << "state = " << getStateName() << "\n";
|
596
|
-
if (session == NULL) {
|
597
|
-
stream << indent << "session = NULL\n";
|
598
|
-
} else {
|
599
|
-
stream << indent << "session pid = " << session->getPid() << " (" <<
|
600
|
-
session->getGroup()->name << ")\n";
|
601
|
-
stream << indent << "session gupid = " << session->getGupid() << "\n";
|
602
|
-
stream << indent << "session initiated = " << boolStr(session->initiated()) << "\n";
|
603
|
-
}
|
604
|
-
stream
|
605
|
-
<< indent << "requestBodyIsBuffered = " << boolStr(requestBodyIsBuffered) << "\n"
|
606
|
-
<< indent << "requestIsChunked = " << boolStr(requestIsChunked) << "\n"
|
607
|
-
<< indent << "requestBodyLength = " << requestBodyLength << "\n"
|
608
|
-
<< indent << "requestBodyAlreadyRead = " << requestBodyAlreadyRead << "\n"
|
609
|
-
<< indent << "responseContentLength = " << responseContentLength << "\n"
|
610
|
-
<< indent << "responseBodyAlreadyRead = " << responseBodyAlreadyRead << "\n"
|
611
|
-
<< indent << "clientInput = " << clientInput.get() << " " << clientInput->inspect() << "\n"
|
612
|
-
<< indent << "clientInput started = " << boolStr(clientInput->isStarted()) << "\n"
|
613
|
-
<< indent << "clientBodyBuffer started = " << boolStr(clientBodyBuffer->isStarted()) << "\n"
|
614
|
-
<< indent << "clientBodyBuffer reachedEnd = " << boolStr(clientBodyBuffer->reachedEnd()) << "\n"
|
615
|
-
<< indent << "clientOutputPipe started = " << boolStr(clientOutputPipe->isStarted()) << "\n"
|
616
|
-
<< indent << "clientOutputPipe reachedEnd = " << boolStr(clientOutputPipe->reachedEnd()) << "\n"
|
617
|
-
<< indent << "clientOutputWatcher active = " << boolStr(clientOutputWatcher.is_active()) << "\n"
|
618
|
-
<< indent << "appInput = " << appInput.get() << " " << appInput->inspect() << "\n"
|
619
|
-
<< indent << "appInput started = " << boolStr(appInput->isStarted()) << "\n"
|
620
|
-
<< indent << "appInput reachedEnd = " << boolStr(appInput->endReached()) << "\n"
|
621
|
-
<< indent << "responseHeaderSeen = " << boolStr(responseHeaderSeen) << "\n"
|
622
|
-
<< indent << "useUnionStation = " << boolStr(useUnionStation()) << "\n"
|
623
|
-
;
|
624
|
-
}
|
625
|
-
};
|
626
|
-
|
627
|
-
typedef boost::shared_ptr<Client> ClientPtr;
|
628
163
|
|
629
|
-
|
630
|
-
class RequestHandler {
|
164
|
+
class RequestHandler: public ServerKit::HttpServer<RequestHandler, Client> {
|
631
165
|
public:
|
632
|
-
enum
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
166
|
+
enum BenchmarkMode {
|
167
|
+
BM_NONE,
|
168
|
+
BM_AFTER_ACCEPT,
|
169
|
+
BM_BEFORE_CHECKOUT,
|
170
|
+
BM_AFTER_CHECKOUT,
|
171
|
+
BM_RESPONSE_BEGIN,
|
172
|
+
BM_UNKNOWN
|
638
173
|
};
|
639
174
|
|
640
175
|
private:
|
641
|
-
|
176
|
+
typedef ServerKit::HttpServer<RequestHandler, Client> ParentClass;
|
177
|
+
typedef ServerKit::Channel Channel;
|
178
|
+
typedef ServerKit::FdSinkChannel FdSinkChannel;
|
179
|
+
typedef ServerKit::FdSourceChannel FdSourceChannel;
|
180
|
+
typedef ServerKit::FileBufferedChannel FileBufferedChannel;
|
181
|
+
typedef ServerKit::FileBufferedFdSinkChannel FileBufferedFdSinkChannel;
|
182
|
+
|
183
|
+
static const unsigned int MAX_SESSION_CHECKOUT_TRY = 10;
|
184
|
+
|
185
|
+
unsigned int statThrottleRate;
|
186
|
+
BenchmarkMode benchmarkMode: 3;
|
187
|
+
bool singleAppMode: 1;
|
188
|
+
bool showVersionInHeader: 1;
|
189
|
+
bool gracefulExit: 1;
|
190
|
+
|
191
|
+
const VariantMap *agentsOptions;
|
192
|
+
psg_pool_t *stringPool;
|
193
|
+
StringKeyTable< boost::shared_ptr<Options> > poolOptionsCache;
|
194
|
+
|
195
|
+
StaticString defaultRuby;
|
196
|
+
StaticString loggingAgentAddress;
|
197
|
+
StaticString loggingAgentPassword;
|
198
|
+
StaticString defaultUser;
|
199
|
+
StaticString defaultGroup;
|
200
|
+
StaticString defaultServerName;
|
201
|
+
StaticString defaultServerPort;
|
202
|
+
StaticString serverSoftware;
|
203
|
+
|
204
|
+
HashedStaticString PASSENGER_APP_GROUP_NAME;
|
205
|
+
HashedStaticString PASSENGER_MAX_REQUESTS;
|
206
|
+
HashedStaticString PASSENGER_STICKY_SESSIONS;
|
207
|
+
HashedStaticString PASSENGER_STICKY_SESSIONS_COOKIE_NAME;
|
208
|
+
HashedStaticString PASSENGER_REQUEST_OOB_WORK;
|
209
|
+
HashedStaticString UNION_STATION_SUPPORT;
|
210
|
+
HashedStaticString REMOTE_ADDR;
|
211
|
+
HashedStaticString REMOTE_PORT;
|
212
|
+
HashedStaticString REMOTE_USER;
|
213
|
+
HashedStaticString FLAGS;
|
214
|
+
HashedStaticString HTTP_COOKIE;
|
215
|
+
HashedStaticString HTTP_DATE;
|
216
|
+
HashedStaticString HTTP_HOST;
|
217
|
+
HashedStaticString HTTP_CONTENT_LENGTH;
|
218
|
+
HashedStaticString HTTP_CONTENT_TYPE;
|
219
|
+
HashedStaticString HTTP_EXPECT;
|
220
|
+
HashedStaticString HTTP_CONNECTION;
|
221
|
+
HashedStaticString HTTP_STATUS;
|
222
|
+
HashedStaticString HTTP_TRANSFER_ENCODING;
|
223
|
+
|
224
|
+
unsigned int threadNumber;
|
225
|
+
StaticString serverLogName;
|
226
|
+
|
227
|
+
friend class TurboCaching<Request>;
|
228
|
+
struct ev_check checkWatcher;
|
229
|
+
TurboCaching<Request> turboCaching;
|
230
|
+
|
231
|
+
#ifdef DEBUG_RH_EVENT_LOOP_BLOCKING
|
232
|
+
struct ev_prepare prepareWatcher;
|
233
|
+
ev_tstamp timeBeforeBlocking;
|
234
|
+
#endif
|
642
235
|
|
643
|
-
|
644
|
-
|
645
|
-
PoolPtr
|
646
|
-
const AgentOptions &options;
|
647
|
-
const ResourceLocator resourceLocator;
|
236
|
+
public:
|
237
|
+
ResourceLocator *resourceLocator;
|
238
|
+
PoolPtr appPool;
|
648
239
|
UnionStation::CorePtr unionStationCore;
|
649
|
-
ev::io requestSocketWatcher;
|
650
|
-
ev::timer resumeSocketWatcherTimer;
|
651
|
-
HashMap<int, ClientPtr> clients;
|
652
|
-
Timer inactivityTimer;
|
653
|
-
bool accept4Available;
|
654
|
-
boost::regex upgradeHeaderRegex;
|
655
|
-
|
656
|
-
|
657
|
-
void disconnect(const ClientPtr &client) {
|
658
|
-
// Prevent Client object from being destroyed until we're done.
|
659
|
-
ClientPtr reference = client;
|
660
|
-
|
661
|
-
clients.erase(client->fd);
|
662
|
-
client->discard();
|
663
|
-
client->verifyInvariants();
|
664
|
-
RH_DEBUG(client, "Disconnected; new client count = " << clients.size());
|
665
|
-
|
666
|
-
if (clients.empty()) {
|
667
|
-
inactivityTimer.start();
|
668
|
-
}
|
669
|
-
}
|
670
|
-
|
671
|
-
void disconnectWithError(const ClientPtr &client, const StaticString &message) {
|
672
|
-
RH_WARN(client, "Disconnecting with error: " << message);
|
673
|
-
if (client->useUnionStation()) {
|
674
|
-
client->logMessage("Disconnecting with error: " + message);
|
675
|
-
}
|
676
|
-
disconnect(client);
|
677
|
-
}
|
678
|
-
|
679
|
-
void disconnectWithClientSocketWriteError(const ClientPtr &client, int e) {
|
680
|
-
stringstream message;
|
681
|
-
message << "client socket write error: ";
|
682
|
-
message << strerror(e);
|
683
|
-
message << " (errno=" << e << ")";
|
684
|
-
disconnectWithError(client, message.str());
|
685
|
-
}
|
686
|
-
|
687
|
-
void disconnectWithAppSocketWriteError(const ClientPtr &client, int e) {
|
688
|
-
stringstream message;
|
689
|
-
message << "app socket write error: ";
|
690
|
-
message << strerror(e);
|
691
|
-
message << " (errno=" << e << ")";
|
692
|
-
disconnectWithError(client, message.str());
|
693
|
-
}
|
694
|
-
|
695
|
-
void disconnectWithWarning(const ClientPtr &client, const StaticString &message) {
|
696
|
-
P_DEBUG("Disconnected client " << client->name() << " with warning: " << message);
|
697
|
-
disconnect(client);
|
698
|
-
}
|
699
|
-
|
700
|
-
template<typename Number>
|
701
|
-
static Number clamp(Number n, Number min, Number max) {
|
702
|
-
if (n < min) {
|
703
|
-
return min;
|
704
|
-
} else if (n > max) {
|
705
|
-
return max;
|
706
|
-
} else {
|
707
|
-
return n;
|
708
|
-
}
|
709
|
-
}
|
710
|
-
|
711
|
-
// GDB helper function, implemented in .cpp file to prevent inlining.
|
712
|
-
Client *getClientPointer(const ClientPtr &client);
|
713
|
-
|
714
|
-
void doResetInactivityTime() {
|
715
|
-
inactivityTimer.reset();
|
716
|
-
}
|
717
|
-
|
718
|
-
void getInactivityTime(unsigned long long *result) const {
|
719
|
-
*result = inactivityTimer.elapsed();
|
720
|
-
}
|
721
|
-
|
722
|
-
static bool getBoolOption(const ClientPtr &client, const StaticString &name, bool defaultValue = false) {
|
723
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
724
|
-
if (it != client->scgiParser.end()) {
|
725
|
-
return it->second == "true";
|
726
|
-
} else {
|
727
|
-
return defaultValue;
|
728
|
-
}
|
729
|
-
}
|
730
|
-
|
731
|
-
static long long getULongLongOption(const ClientPtr &client, const StaticString &name, long long defaultValue = -1) {
|
732
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
733
|
-
if (it != client->scgiParser.end()) {
|
734
|
-
long long result = stringToULL(it->second);
|
735
|
-
// The client may send a malicious integer, so check for this.
|
736
|
-
if (result < 0) {
|
737
|
-
return defaultValue;
|
738
|
-
} else {
|
739
|
-
return result;
|
740
|
-
}
|
741
|
-
} else {
|
742
|
-
return defaultValue;
|
743
|
-
}
|
744
|
-
}
|
745
|
-
|
746
|
-
bool friendlyErrorPagesEnabled(const ClientPtr &client) const {
|
747
|
-
bool defaultValue = client->options.environment != "staging"
|
748
|
-
&& client->options.environment != "production";
|
749
|
-
return getBoolOption(client, "PASSENGER_FRIENDLY_ERROR_PAGES", defaultValue);
|
750
|
-
}
|
751
|
-
|
752
|
-
void writeSimpleResponse(const ClientPtr &client, const StaticString &data, int code = 200) {
|
753
|
-
char header[256], statusBuffer[50];
|
754
|
-
char *pos = header;
|
755
|
-
const char *end = header + sizeof(header) - 1;
|
756
|
-
const char *status;
|
757
|
-
|
758
|
-
status = getStatusCodeAndReasonPhrase(code);
|
759
|
-
if (status == NULL) {
|
760
|
-
snprintf(statusBuffer, sizeof(statusBuffer), "%d Unknown Reason-Phrase", code);
|
761
|
-
status = statusBuffer;
|
762
|
-
}
|
763
|
-
|
764
|
-
if (getBoolOption(client, "PASSENGER_STATUS_LINE", true)) {
|
765
|
-
pos += snprintf(pos, end - pos, "HTTP/1.1 %s\r\n",
|
766
|
-
status);
|
767
|
-
}
|
768
|
-
pos += snprintf(pos, end - pos,
|
769
|
-
"Status: %s\r\n"
|
770
|
-
"Content-Length: %lu\r\n"
|
771
|
-
"Content-Type: text/html; charset=UTF-8\r\n"
|
772
|
-
"Cache-Control: no-cache, no-store, must-revalidate\r\n"
|
773
|
-
"\r\n",
|
774
|
-
status, (unsigned long) data.size());
|
775
|
-
|
776
|
-
client->clientOutputPipe->write(header, pos - header);
|
777
|
-
if (!client->connected()) {
|
778
|
-
return;
|
779
|
-
}
|
780
|
-
client->clientOutputPipe->write(data.data(), data.size());
|
781
|
-
if (!client->connected()) {
|
782
|
-
return;
|
783
|
-
}
|
784
|
-
client->clientOutputPipe->end();
|
785
|
-
if (!client->connected()) {
|
786
|
-
return;
|
787
|
-
}
|
788
|
-
|
789
|
-
if (client->useUnionStation()) {
|
790
|
-
snprintf(header, end - header, "Status: %d %s",
|
791
|
-
code, status);
|
792
|
-
client->logMessage(header);
|
793
|
-
}
|
794
|
-
}
|
795
|
-
|
796
|
-
void writeErrorResponse(const ClientPtr &client, const StaticString &message, const SpawnException *e = NULL) {
|
797
|
-
assert(client->state < Client::FORWARDING_BODY_TO_APP);
|
798
|
-
client->state = Client::WRITING_SIMPLE_RESPONSE;
|
799
|
-
|
800
|
-
ErrorRenderer renderer(resourceLocator);
|
801
|
-
string data;
|
802
|
-
|
803
|
-
if (friendlyErrorPagesEnabled(client)) {
|
804
|
-
try {
|
805
|
-
data = renderer.renderWithDetails(message, client->options, e);
|
806
|
-
} catch (const SystemException &e2) {
|
807
|
-
P_ERROR("Cannot render an error page: " << e2.what() << "\n" <<
|
808
|
-
e2.backtrace());
|
809
|
-
data = message;
|
810
|
-
}
|
811
|
-
} else {
|
812
|
-
try {
|
813
|
-
data = renderer.renderWithoutDetails();
|
814
|
-
} catch (const SystemException &e2) {
|
815
|
-
P_ERROR("Cannot render an error page: " << e2.what() << "\n" <<
|
816
|
-
e2.backtrace());
|
817
|
-
data = "Internal Server Error";
|
818
|
-
}
|
819
|
-
}
|
820
|
-
|
821
|
-
stringstream str;
|
822
|
-
if (getBoolOption(client, "PASSENGER_STATUS_LINE", true)) {
|
823
|
-
str << "HTTP/1.1 500 Internal Server Error\r\n";
|
824
|
-
}
|
825
|
-
str << "Status: 500 Internal Server Error\r\n";
|
826
|
-
str << "Content-Length: " << data.size() << "\r\n";
|
827
|
-
str << "Content-Type: text/html; charset=UTF-8\r\n";
|
828
|
-
str << "Cache-Control: no-cache, no-store, must-revalidate\r\n";
|
829
|
-
str << "\r\n";
|
830
|
-
|
831
|
-
const string header = str.str();
|
832
|
-
client->clientOutputPipe->write(header.data(), header.size());
|
833
|
-
if (!client->connected()) {
|
834
|
-
return;
|
835
|
-
}
|
836
|
-
client->clientOutputPipe->write(data.data(), data.size());
|
837
|
-
if (!client->connected()) {
|
838
|
-
return;
|
839
|
-
}
|
840
|
-
client->clientOutputPipe->end();
|
841
|
-
if (!client->connected()) {
|
842
|
-
return;
|
843
|
-
}
|
844
|
-
|
845
|
-
if (client->useUnionStation()) {
|
846
|
-
client->logMessage("Status: 500 Internal Server Error");
|
847
|
-
// TODO: record error message
|
848
|
-
}
|
849
|
-
}
|
850
|
-
|
851
|
-
static BenchmarkPoint getDefaultBenchmarkPoint() {
|
852
|
-
const char *val = getenv("PASSENGER_REQUEST_HANDLER_BENCHMARK_POINT");
|
853
|
-
if (val == NULL || *val == '\0') {
|
854
|
-
return BP_NONE;
|
855
|
-
} else if (strcmp(val, "after_accept") == 0) {
|
856
|
-
return BP_AFTER_ACCEPT;
|
857
|
-
} else if (strcmp(val, "after_check_connect_password") == 0) {
|
858
|
-
return BP_AFTER_CHECK_CONNECT_PASSWORD;
|
859
|
-
} else if (strcmp(val, "after_parsing_header") == 0) {
|
860
|
-
return BP_AFTER_PARSING_HEADER;
|
861
|
-
} else if (strcmp(val, "before_checkout_session") == 0) {
|
862
|
-
return BP_BEFORE_CHECKOUT_SESSION;
|
863
|
-
} else {
|
864
|
-
P_WARN("Invalid RequestHandler benchmark point requested: " << val);
|
865
|
-
return BP_NONE;
|
866
|
-
}
|
867
|
-
}
|
868
|
-
|
869
|
-
|
870
|
-
/*****************************************************
|
871
|
-
* COMPONENT: appInput -> clientOutputPipe plumbing
|
872
|
-
*
|
873
|
-
* The following code receives data from appInput,
|
874
|
-
* possibly modifies it, and forwards it to
|
875
|
-
* clientOutputPipe.
|
876
|
-
*****************************************************/
|
877
|
-
|
878
|
-
struct Header {
|
879
|
-
StaticString key;
|
880
|
-
StaticString value;
|
881
|
-
|
882
|
-
Header() { }
|
883
|
-
|
884
|
-
Header(const StaticString &_key, const StaticString &_value)
|
885
|
-
: key(_key),
|
886
|
-
value(_value)
|
887
|
-
{ }
|
888
|
-
|
889
|
-
bool empty() const {
|
890
|
-
return key.empty();
|
891
|
-
}
|
892
|
-
|
893
|
-
const char *begin() const {
|
894
|
-
return key.data();
|
895
|
-
}
|
896
|
-
|
897
|
-
const char *end() const {
|
898
|
-
return value.data() + value.size() + sizeof("\r\n") - 1;
|
899
|
-
}
|
900
|
-
|
901
|
-
size_t size() const {
|
902
|
-
return end() - begin();
|
903
|
-
}
|
904
|
-
};
|
905
|
-
|
906
|
-
/** Given a substring containing the start of the header value,
|
907
|
-
* extracts the substring that contains a single header value.
|
908
|
-
*
|
909
|
-
* const char *data =
|
910
|
-
* "Status: 200 OK\r\n"
|
911
|
-
* "Foo: bar\r\n";
|
912
|
-
* extractHeaderValue(data + strlen("Status:"), strlen(data) - strlen("Status:"));
|
913
|
-
* // "200 OK"
|
914
|
-
*/
|
915
|
-
static StaticString extractHeaderValue(const char *data, size_t size) {
|
916
|
-
const char *start = data;
|
917
|
-
const char *end = data + size;
|
918
|
-
const char *terminator;
|
919
|
-
|
920
|
-
while (start < end && *start == ' ') {
|
921
|
-
start++;
|
922
|
-
}
|
923
|
-
|
924
|
-
terminator = (const char *) memchr(start, '\r', end - start);
|
925
|
-
if (terminator == NULL) {
|
926
|
-
return StaticString();
|
927
|
-
} else {
|
928
|
-
return StaticString(start, terminator - start);
|
929
|
-
}
|
930
|
-
}
|
931
240
|
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
&& headerData[pos + name.size()] == ':')
|
941
|
-
{
|
942
|
-
StaticString value = extractHeaderValue(
|
943
|
-
headerData.data() + pos + name.size() + 1,
|
944
|
-
headerData.size() - pos - name.size() - 1);
|
945
|
-
return Header(headerData.substr(pos, name.size()), value);
|
946
|
-
} else {
|
947
|
-
searchStart = pos + name.size() + 1;
|
948
|
-
}
|
949
|
-
}
|
950
|
-
return Header();
|
951
|
-
}
|
241
|
+
protected:
|
242
|
+
#include <agents/HelperAgent/RequestHandler/Utils.cpp>
|
243
|
+
#include <agents/HelperAgent/RequestHandler/Hooks.cpp>
|
244
|
+
#include <agents/HelperAgent/RequestHandler/InitRequest.cpp>
|
245
|
+
#include <agents/HelperAgent/RequestHandler/BufferBody.cpp>
|
246
|
+
#include <agents/HelperAgent/RequestHandler/CheckoutSession.cpp>
|
247
|
+
#include <agents/HelperAgent/RequestHandler/SendRequest.cpp>
|
248
|
+
#include <agents/HelperAgent/RequestHandler/ForwardResponse.cpp>
|
952
249
|
|
953
|
-
|
954
|
-
|
250
|
+
public:
|
251
|
+
RequestHandler(ServerKit::Context *context, const VariantMap *_agentsOptions,
|
252
|
+
unsigned int _threadNumber = 1)
|
253
|
+
: ParentClass(context),
|
254
|
+
|
255
|
+
statThrottleRate(_agentsOptions->getInt("stat_throttle_rate")),
|
256
|
+
benchmarkMode(parseBenchmarkMode(_agentsOptions->get("benchmark_mode", false))),
|
257
|
+
singleAppMode(false),
|
258
|
+
showVersionInHeader(_agentsOptions->getBool("show_version_in_header")),
|
259
|
+
gracefulExit(_agentsOptions->getBool("server_graceful_exit")),
|
260
|
+
|
261
|
+
agentsOptions(_agentsOptions),
|
262
|
+
stringPool(psg_create_pool(1024 * 4)),
|
263
|
+
poolOptionsCache(4),
|
264
|
+
|
265
|
+
PASSENGER_APP_GROUP_NAME("!~PASSENGER_APP_GROUP_NAME"),
|
266
|
+
PASSENGER_MAX_REQUESTS("!~PASSENGER_MAX_REQUESTS"),
|
267
|
+
PASSENGER_STICKY_SESSIONS("!~PASSENGER_STICKY_SESSIONS"),
|
268
|
+
PASSENGER_STICKY_SESSIONS_COOKIE_NAME("!~PASSENGER_STICKY_SESSIONS_COOKIE_NAME"),
|
269
|
+
PASSENGER_REQUEST_OOB_WORK("!~Request-OOB-Work"),
|
270
|
+
UNION_STATION_SUPPORT("!~UNION_STATION_SUPPORT"),
|
271
|
+
REMOTE_ADDR("!~REMOTE_ADDR"),
|
272
|
+
REMOTE_PORT("!~REMOTE_PORT"),
|
273
|
+
REMOTE_USER("!~REMOTE_USER"),
|
274
|
+
FLAGS("!~FLAGS"),
|
275
|
+
HTTP_COOKIE("cookie"),
|
276
|
+
HTTP_DATE("date"),
|
277
|
+
HTTP_HOST("host"),
|
278
|
+
HTTP_CONTENT_LENGTH("content-length"),
|
279
|
+
HTTP_CONTENT_TYPE("content-type"),
|
280
|
+
HTTP_EXPECT("expect"),
|
281
|
+
HTTP_CONNECTION("connection"),
|
282
|
+
HTTP_STATUS("status"),
|
283
|
+
HTTP_TRANSFER_ENCODING("transfer-encoding"),
|
284
|
+
|
285
|
+
threadNumber(_threadNumber),
|
286
|
+
turboCaching(getTurboCachingInitialState(_agentsOptions))
|
955
287
|
{
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
}
|
991
|
-
|
992
|
-
|
993
|
-
|
288
|
+
defaultRuby = psg_pstrdup(stringPool,
|
289
|
+
agentsOptions->get("default_ruby"));
|
290
|
+
loggingAgentAddress = psg_pstrdup(stringPool,
|
291
|
+
agentsOptions->get("logging_agent_address", false));
|
292
|
+
loggingAgentPassword = psg_pstrdup(stringPool,
|
293
|
+
agentsOptions->get("logging_agent_password", false));
|
294
|
+
defaultUser = psg_pstrdup(stringPool,
|
295
|
+
agentsOptions->get("default_user", false));
|
296
|
+
defaultGroup = psg_pstrdup(stringPool,
|
297
|
+
agentsOptions->get("default_group", false));
|
298
|
+
defaultServerName = psg_pstrdup(stringPool,
|
299
|
+
agentsOptions->get("default_server_name"));
|
300
|
+
defaultServerPort = psg_pstrdup(stringPool,
|
301
|
+
agentsOptions->get("default_server_port"));
|
302
|
+
serverSoftware = psg_pstrdup(stringPool,
|
303
|
+
agentsOptions->get("server_software"));
|
304
|
+
|
305
|
+
generateServerLogName(_threadNumber);
|
306
|
+
|
307
|
+
if (!agentsOptions->getBool("multi_app")) {
|
308
|
+
boost::shared_ptr<Options> options = boost::make_shared<Options>();
|
309
|
+
|
310
|
+
singleAppMode = true;
|
311
|
+
fillPoolOptionsFromAgentsOptions(*options);
|
312
|
+
|
313
|
+
options->appRoot = psg_pstrdup(stringPool,
|
314
|
+
agentsOptions->get("app_root"));
|
315
|
+
options->environment = psg_pstrdup(stringPool,
|
316
|
+
agentsOptions->get("environment"));
|
317
|
+
options->appType = psg_pstrdup(stringPool,
|
318
|
+
agentsOptions->get("app_type"));
|
319
|
+
options->startupFile = psg_pstrdup(stringPool,
|
320
|
+
agentsOptions->get("startup_file"));
|
321
|
+
poolOptionsCache.insert(options->getAppGroupName(), options);
|
322
|
+
}
|
323
|
+
|
324
|
+
ev_check_init(&checkWatcher, onEventLoopCheck);
|
325
|
+
ev_set_priority(&checkWatcher, EV_MAXPRI);
|
326
|
+
ev_check_start(getLoop(), &checkWatcher);
|
327
|
+
checkWatcher.data = this;
|
328
|
+
|
329
|
+
#ifdef DEBUG_RH_EVENT_LOOP_BLOCKING
|
330
|
+
ev_prepare_init(&prepareWatcher, onEventLoopPrepare);
|
331
|
+
ev_prepare_start(getLoop(), &prepareWatcher);
|
332
|
+
prepareWatcher.data = this;
|
333
|
+
|
334
|
+
timeBeforeBlocking = 0;
|
335
|
+
#endif
|
994
336
|
}
|
995
337
|
|
996
|
-
|
997
|
-
|
998
|
-
int statusCode = stringToInt(status.value);
|
999
|
-
const char *statusCodeAndReasonPhrase = getStatusCodeAndReasonPhrase(statusCode);
|
1000
|
-
char newStatus[100];
|
1001
|
-
char *pos = newStatus;
|
1002
|
-
const char *end = newStatus + sizeof(newStatus);
|
1003
|
-
|
1004
|
-
pos = appendData(pos, end, "Status: ");
|
1005
|
-
if (statusCodeAndReasonPhrase == NULL) {
|
1006
|
-
pos = appendData(pos, end, toString(statusCode));
|
1007
|
-
pos = appendData(pos, end, " Unknown Reason-Phrase\r\n");
|
1008
|
-
} else {
|
1009
|
-
pos = appendData(pos, end, statusCodeAndReasonPhrase);
|
1010
|
-
pos = appendData(pos, end, "\r\n");
|
1011
|
-
}
|
1012
|
-
|
1013
|
-
headerData.replace(status.begin() - headerData.data(), status.size(),
|
1014
|
-
newStatus, pos - newStatus);
|
1015
|
-
return true;
|
1016
|
-
} else {
|
1017
|
-
return false;
|
1018
|
-
}
|
338
|
+
~RequestHandler() {
|
339
|
+
psg_destroy_pool(stringPool);
|
1019
340
|
}
|
1020
341
|
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
return
|
342
|
+
static BenchmarkMode parseBenchmarkMode(const StaticString mode) {
|
343
|
+
if (mode.empty()) {
|
344
|
+
return BM_NONE;
|
345
|
+
} else if (mode == "after_accept") {
|
346
|
+
return BM_AFTER_ACCEPT;
|
347
|
+
} else if (mode == "before_checkout") {
|
348
|
+
return BM_BEFORE_CHECKOUT;
|
349
|
+
} else if (mode == "after_checkout") {
|
350
|
+
return BM_AFTER_CHECKOUT;
|
351
|
+
} else if (mode == "response_begin") {
|
352
|
+
return BM_RESPONSE_BEGIN;
|
1026
353
|
} else {
|
1027
|
-
|
1028
|
-
return false;
|
354
|
+
return BM_UNKNOWN;
|
1029
355
|
}
|
1030
356
|
}
|
1031
357
|
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
pos = appendData(pos, end, "HTTP/1.1 ");
|
1038
|
-
pos = appendData(pos, end, status.value);
|
1039
|
-
pos = appendData(pos, end, "\r\n");
|
1040
|
-
|
1041
|
-
headerData.insert(0, statusLine, pos - statusLine);
|
1042
|
-
}
|
1043
|
-
|
1044
|
-
static void removeHeader(string &headerData, const Header &header) {
|
1045
|
-
headerData.erase(header.begin() - headerData.data(), header.size());
|
1046
|
-
}
|
1047
|
-
|
1048
|
-
/*
|
1049
|
-
* Given a full header, possibly modify the header and send it to the clientOutputPipe.
|
1050
|
-
*/
|
1051
|
-
bool processResponseHeader(const ClientPtr &client,
|
1052
|
-
const StaticString &origHeaderData)
|
1053
|
-
{
|
1054
|
-
string headerData;
|
1055
|
-
headerData.reserve(origHeaderData.size() + 150);
|
1056
|
-
// Strip trailing CRLF.
|
1057
|
-
headerData.append(origHeaderData.data(), origHeaderData.size() - 2);
|
1058
|
-
|
1059
|
-
if (startsWith(headerData, "HTTP/1.")) {
|
1060
|
-
Header status = lookupHeader(headerData, "Status", "status");
|
1061
|
-
if (status.empty()) {
|
1062
|
-
// Add status header if necessary.
|
1063
|
-
if (!addStatusHeaderFromStatusLine(client, headerData)) {
|
1064
|
-
return false;
|
1065
|
-
}
|
1066
|
-
} else {
|
1067
|
-
// Add reason phrase to existing status header if necessary.
|
1068
|
-
addReasonPhrase(headerData, status);
|
1069
|
-
}
|
1070
|
-
// Remove status line if necesary.
|
1071
|
-
if (!getBoolOption(client, "PASSENGER_STATUS_LINE", true)) {
|
1072
|
-
if (!removeStatusLine(client, headerData)) {
|
1073
|
-
return false;
|
1074
|
-
}
|
1075
|
-
}
|
1076
|
-
} else {
|
1077
|
-
Header status = lookupHeader(headerData, "Status", "status");
|
1078
|
-
if (!status.empty()) {
|
1079
|
-
// Add reason phrase to status header if necessary.
|
1080
|
-
if (addReasonPhrase(headerData, status)) {
|
1081
|
-
status = lookupHeader(headerData, "Status", "status");
|
1082
|
-
}
|
1083
|
-
// Add status line if necessary.
|
1084
|
-
if (getBoolOption(client, "PASSENGER_STATUS_LINE", true)) {
|
1085
|
-
addStatusLineFromStatusHeader(headerData, status);
|
1086
|
-
}
|
1087
|
-
} else {
|
1088
|
-
disconnectWithError(client, "application sent malformed response: it didn't send an HTTP status line or a Status header.");
|
1089
|
-
return false;
|
1090
|
-
}
|
1091
|
-
}
|
1092
|
-
|
1093
|
-
if (client->useUnionStation()) {
|
1094
|
-
Header status = lookupHeader(headerData, "Status", "status");
|
1095
|
-
string message = "Status: ";
|
1096
|
-
message.append(status.value);
|
1097
|
-
client->logMessage(message);
|
358
|
+
void initialize() {
|
359
|
+
TRACE_POINT();
|
360
|
+
if (resourceLocator == NULL) {
|
361
|
+
throw RuntimeException("ResourceLocator not initialized");
|
1098
362
|
}
|
1099
|
-
|
1100
|
-
|
1101
|
-
Header transferEncoding = lookupHeader(headerData, "Transfer-Encoding", "transfer-encoding");
|
1102
|
-
if (!transferEncoding.empty() && transferEncoding.value == "chunked") {
|
1103
|
-
RH_TRACE(client, 3, "Response with chunked transfer encoding detected.");
|
1104
|
-
client->chunkedResponse = true;
|
1105
|
-
removeHeader(headerData, transferEncoding);
|
1106
|
-
} else {
|
1107
|
-
Header contentLength = lookupHeader(headerData, "Content-Length", "content-length");
|
1108
|
-
if (!contentLength.empty()) {
|
1109
|
-
client->responseContentLength = stringToLL(contentLength.value);
|
1110
|
-
}
|
363
|
+
if (appPool == NULL) {
|
364
|
+
throw RuntimeException("AppPool not initialized");
|
1111
365
|
}
|
1112
|
-
|
1113
|
-
|
1114
|
-
if (!connection.empty() && (connection.value == "keep-alive"
|
1115
|
-
|| connection.value == "Keep-Alive"))
|
1116
|
-
{
|
1117
|
-
RH_TRACE(client, 3, "Keep-alive response detected. Changing to non-keep alive.");
|
1118
|
-
removeHeader(headerData, connection);
|
1119
|
-
headerData.append("Connection: close\r\n");
|
366
|
+
if (unionStationCore == NULL) {
|
367
|
+
unionStationCore = appPool->getUnionStationCore();
|
1120
368
|
}
|
369
|
+
}
|
1121
370
|
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
headerData.append("X-Powered-By: Phusion Passenger\r\n");
|
1127
|
-
}
|
371
|
+
void disconnectLongRunningConnections(const StaticString &gupid) {
|
372
|
+
vector<Client *> clients;
|
373
|
+
vector<Client *>::iterator v_it, v_end;
|
374
|
+
Client *client;
|
1128
375
|
|
1129
|
-
//
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
376
|
+
// We collect all clients in a vector so that we don't have to worry about
|
377
|
+
// `activeClients` being mutated while we work.
|
378
|
+
TAILQ_FOREACH (client, &activeClients, nextClient.activeOrDisconnectedClient) {
|
379
|
+
P_ASSERT_EQ(client->getConnState(), Client::ACTIVE);
|
380
|
+
if (client->currentRequest != NULL) {
|
381
|
+
Request *req = client->currentRequest;
|
382
|
+
if (req->httpState >= Request::COMPLETE
|
383
|
+
&& req->upgraded()
|
384
|
+
&& req->session != NULL
|
385
|
+
&& req->session->getGupid() == gupid)
|
386
|
+
{
|
387
|
+
if (getLogLevel() >= LVL_INFO) {
|
388
|
+
char clientName[32];
|
389
|
+
unsigned int size;
|
390
|
+
const LString *host;
|
391
|
+
StaticString hostStr;
|
1135
392
|
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
headerData.append(baseURI.data(), baseURI.size());
|
1145
|
-
headerData.append("\r\n");
|
1146
|
-
|
1147
|
-
// Invalidate all cookies with a different route.
|
1148
|
-
//
|
1149
|
-
// TODO: This is not entirely correct. Clients MAY send multiple Cookie
|
1150
|
-
// headers, although this is in practice extremely rare.
|
1151
|
-
// http://stackoverflow.com/questions/16305814/are-multiple-cookie-headers-allowed-in-an-http-request
|
1152
|
-
StaticString cookieHeader = client->scgiParser.getHeader("HTTP_COOKIE");
|
1153
|
-
vector< pair<StaticString, StaticString> > cookies;
|
1154
|
-
pair<StaticString, StaticString> cookie;
|
1155
|
-
|
1156
|
-
parseCookieHeader(cookieHeader, cookies);
|
1157
|
-
|
1158
|
-
foreach (cookie, cookies) {
|
1159
|
-
if (cookie.first == cookieName) {
|
1160
|
-
unsigned int stickySessionId = stringToUint(cookie.second);
|
1161
|
-
if (stickySessionId != client->session->getStickySessionId()) {
|
1162
|
-
headerData.append("Set-Cookie: ");
|
1163
|
-
headerData.append(cookie.first.data(), cookie.first.size());
|
1164
|
-
headerData.append("=");
|
1165
|
-
headerData.append(cookie.second.data(), cookie.second.size());
|
1166
|
-
headerData.append("; Path=");
|
1167
|
-
headerData.append(baseURI.data(), baseURI.size());
|
1168
|
-
headerData.append("; Expires=Thu, 01 Jan 1970 00:00:00 GMT\r\n");
|
393
|
+
size = getClientName(client, clientName, sizeof(clientName));
|
394
|
+
if (req->host != NULL) {
|
395
|
+
host = psg_lstr_make_contiguous(req->host, req->pool);
|
396
|
+
hostStr = StaticString(host->start->data, host->size);
|
397
|
+
}
|
398
|
+
P_INFO("[" << getServerName() << "] Disconnecting client " <<
|
399
|
+
StaticString(clientName, size) << ": " <<
|
400
|
+
hostStr << StaticString(req->path.start->data, req->path.size));
|
1169
401
|
}
|
402
|
+
refClient(client, __FILE__, __LINE__);
|
403
|
+
clients.push_back(client);
|
1170
404
|
}
|
1171
405
|
}
|
1172
406
|
}
|
1173
407
|
|
1174
|
-
//
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
pos = appendData(pos, end, "Date: ");
|
1183
|
-
gmtime_r(&the_time, &the_tm);
|
1184
|
-
pos += strftime(pos, end - pos, "%a, %d %b %Y %H:%M:%S %Z", &the_tm);
|
1185
|
-
pos = appendData(pos, end, "\r\n");
|
1186
|
-
headerData.append(dateStr, pos - dateStr);
|
1187
|
-
}
|
1188
|
-
|
1189
|
-
// Detect out of band work request
|
1190
|
-
Header oobw = lookupHeader(headerData, "X-Passenger-Request-OOB-Work", "x-passenger-request-oob-work");
|
1191
|
-
if (!oobw.empty()) {
|
1192
|
-
P_TRACE(3, "Response with oobw detected.");
|
1193
|
-
if (client->session != NULL) {
|
1194
|
-
client->session->requestOOBW();
|
1195
|
-
}
|
1196
|
-
removeHeader(headerData, oobw);
|
408
|
+
// Disconnect each eligible client.
|
409
|
+
v_end = clients.end();
|
410
|
+
for (v_it = clients.begin(); v_it != v_end; v_it++) {
|
411
|
+
client = *v_it;
|
412
|
+
Client *c = client;
|
413
|
+
disconnect(&client);
|
414
|
+
unrefClient(c, __FILE__, __LINE__);
|
1197
415
|
}
|
1198
|
-
|
1199
|
-
P_TRACE(2, "Fowarding response header from app client: " << headerData);
|
1200
|
-
headerData.append("\r\n");
|
1201
|
-
writeToClientOutputPipe(client, headerData);
|
1202
|
-
return true;
|
1203
416
|
}
|
1204
417
|
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
if (!wasCommittingToDisk && nowCommittingToDisk) {
|
1213
|
-
RH_TRACE(client, 3, "Buffering response data to disk; temporarily stopping application socket.");
|
1214
|
-
client->backgroundOperations++;
|
1215
|
-
// If the data comes from writeErrorResponse(), then appInput is not available.
|
1216
|
-
if (client->session != NULL && client->session->initiated()) {
|
1217
|
-
client->appInput->stop();
|
1218
|
-
}
|
1219
|
-
}
|
418
|
+
virtual Json::Value getConfigAsJson() const {
|
419
|
+
Json::Value doc = ParentClass::getConfigAsJson();
|
420
|
+
doc["single_app_mode"] = singleAppMode;
|
421
|
+
doc["stat_throttle_rate"] = statThrottleRate;
|
422
|
+
doc["show_version_in_header"] = showVersionInHeader;
|
423
|
+
doc["data_buffer_dir"] = getContext()->defaultFileBufferedChannelConfig.bufferDir;
|
424
|
+
return doc;
|
1220
425
|
}
|
1221
426
|
|
1222
|
-
|
1223
|
-
|
1224
|
-
if (
|
1225
|
-
|
427
|
+
virtual void configure(const Json::Value &doc) {
|
428
|
+
ParentClass::configure(doc);
|
429
|
+
if (doc.isMember("show_version_in_header")) {
|
430
|
+
showVersionInHeader = doc["show_version_in_header"].asBool();
|
1226
431
|
}
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
// Buffer the application response until we've encountered the end of the header.
|
1232
|
-
if (!client->responseHeaderSeen) {
|
1233
|
-
size_t consumed = client->responseHeaderBufferer.feed(data.data(), data.size());
|
1234
|
-
if (!client->responseHeaderBufferer.acceptingInput()) {
|
1235
|
-
if (client->responseHeaderBufferer.hasError()) {
|
1236
|
-
disconnectWithError(client, "application response format error (invalid header)");
|
1237
|
-
} else {
|
1238
|
-
// Now that we have a full header, do something with it.
|
1239
|
-
RH_TRACE(client, 3, "Response header fully buffered");
|
1240
|
-
client->responseHeaderSeen = true;
|
1241
|
-
StaticString header = client->responseHeaderBufferer.getData();
|
1242
|
-
if (processResponseHeader(client, header)) {
|
1243
|
-
if (client->responseContentLength == 0) {
|
1244
|
-
RH_TRACE(client, 3, "Disconnecting client because response Content-Length = 0");
|
1245
|
-
onAppInputEof(client);
|
1246
|
-
}
|
1247
|
-
return consumed;
|
1248
|
-
} else {
|
1249
|
-
assert(!client->connected());
|
1250
|
-
}
|
1251
|
-
}
|
1252
|
-
}
|
1253
|
-
// The header has already been processed so forward it
|
1254
|
-
// directly to clientOutputPipe, possibly through a
|
1255
|
-
// dechunker first.
|
1256
|
-
} else if (client->chunkedResponse) {
|
1257
|
-
client->responseDechunker.feed(data.data(), data.size());
|
1258
|
-
} else {
|
1259
|
-
onAppInputChunk(client, data);
|
1260
|
-
}
|
1261
|
-
return data.size();
|
1262
|
-
|
1263
|
-
} else {
|
1264
|
-
onAppInputEof(client);
|
1265
|
-
return 0;
|
432
|
+
if (doc.isMember("data_buffer_dir")) {
|
433
|
+
getContext()->defaultFileBufferedChannelConfig.bufferDir =
|
434
|
+
doc["data_buffer_dir"].asString();
|
1266
435
|
}
|
1267
436
|
}
|
1268
437
|
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
}
|
1281
|
-
|
1282
|
-
client->responseBodyAlreadyRead += data2.size();
|
1283
|
-
assert(client->responseContentLength == -1 || client->responseBodyAlreadyRead <=
|
1284
|
-
(unsigned long long) client->responseContentLength);
|
1285
|
-
if (data2.empty()) {
|
1286
|
-
// Client sent more data than was advertised through
|
1287
|
-
// Content-Length. Ignore them.
|
1288
|
-
return;
|
1289
|
-
}
|
1290
|
-
|
1291
|
-
writeToClientOutputPipe(client, data2);
|
1292
|
-
|
1293
|
-
if (client->responseContentLength > 0) {
|
1294
|
-
RH_TRACE(client, 3, client->responseBodyAlreadyRead << "/" <<
|
1295
|
-
client->responseContentLength <<
|
1296
|
-
" bytes of application data forwarded so far.");
|
1297
|
-
|
1298
|
-
if (client->connected() && (unsigned long long) client->responseContentLength
|
1299
|
-
== client->responseBodyAlreadyRead)
|
1300
|
-
{
|
1301
|
-
RH_TRACE(client, 3, "Disconnecting client because application data has been fully forwarded.");
|
1302
|
-
onAppInputEof(client);
|
1303
|
-
}
|
438
|
+
virtual Json::Value inspectStateAsJson() const {
|
439
|
+
Json::Value doc = ParentClass::inspectStateAsJson();
|
440
|
+
if (turboCaching.isEnabled()) {
|
441
|
+
Json::Value subdoc;
|
442
|
+
subdoc["fetches"] = turboCaching.responseCache.getFetches();
|
443
|
+
subdoc["hits"] = turboCaching.responseCache.getHits();
|
444
|
+
subdoc["hit_ratio"] = turboCaching.responseCache.getHitRatio();
|
445
|
+
subdoc["stores"] = turboCaching.responseCache.getStores();
|
446
|
+
subdoc["store_successes"] = turboCaching.responseCache.getStoreSuccesses();
|
447
|
+
subdoc["store_success_ratio"] = turboCaching.responseCache.getStoreSuccessRatio();
|
448
|
+
doc["turbocaching"] = subdoc;
|
1304
449
|
}
|
450
|
+
return doc;
|
1305
451
|
}
|
1306
452
|
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
453
|
+
virtual Json::Value inspectClientStateAsJson(const Client *client) const {
|
454
|
+
Json::Value doc = ParentClass::inspectClientStateAsJson(client);
|
455
|
+
doc["connected_at"] = timeToJson(client->connectedAt * 1000000.0);
|
456
|
+
return doc;
|
1310
457
|
}
|
1311
458
|
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
// responses with chunked encoding.
|
1316
|
-
// This also ensures that when onAppInputEof() is called twice (e.g. because
|
1317
|
-
// additional data was received after onAppInputChunk has already called onAppInputEof()),
|
1318
|
-
// we don't do things twice.
|
1319
|
-
if (!client->connected() || client->session == NULL) {
|
1320
|
-
return;
|
1321
|
-
}
|
1322
|
-
|
1323
|
-
RH_DEBUG(client, "Application sent EOF");
|
1324
|
-
client->appInput->stop();
|
1325
|
-
client->session.reset();
|
1326
|
-
client->endScopeLog(&client->scopeLogs.requestProxying);
|
1327
|
-
client->clientOutputPipe->end();
|
1328
|
-
}
|
459
|
+
virtual Json::Value inspectRequestStateAsJson(const Request *req) const {
|
460
|
+
Json::Value doc = ParentClass::inspectRequestStateAsJson(req);
|
461
|
+
Json::Value flags;
|
1329
462
|
|
1330
|
-
|
1331
|
-
|
1332
|
-
if (!client->connected()) {
|
1333
|
-
return;
|
463
|
+
if (req->startedAt != 0) {
|
464
|
+
doc["started_at"] = timeToJson(req->startedAt * 1000000.0);
|
1334
465
|
}
|
1335
|
-
|
1336
|
-
if (
|
1337
|
-
|
1338
|
-
// http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket
|
1339
|
-
onAppInputEof(client);
|
1340
|
-
} else {
|
1341
|
-
stringstream message;
|
1342
|
-
message << "application socket read error: ";
|
1343
|
-
message << strerror(errorCode);
|
1344
|
-
message << " (fd=" << client->appInput->getFd();
|
1345
|
-
message << ", errno=" << errorCode << ")";
|
1346
|
-
disconnectWithError(client, message.str());
|
466
|
+
doc["state"] = req->getStateString();
|
467
|
+
if (req->stickySession) {
|
468
|
+
doc["sticky_session_id"] = req->options.stickySessionId;
|
1347
469
|
}
|
1348
|
-
|
470
|
+
doc["sticky_session"] = req->stickySession;
|
471
|
+
doc["session_checkout_try"] = req->sessionCheckoutTry;
|
1349
472
|
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
}
|
473
|
+
flags["dechunk_response"] = req->dechunkResponse;
|
474
|
+
flags["request_body_buffering"] = req->requestBodyBuffering;
|
475
|
+
flags["https"] = req->https;
|
476
|
+
doc["flags"] = flags;
|
1355
477
|
|
1356
|
-
|
1357
|
-
|
1358
|
-
// If the data comes from writeErrorResponse(), then appInput is not available.
|
1359
|
-
if (client->session != NULL && client->session->initiated()) {
|
1360
|
-
client->appInput->start();
|
478
|
+
if (req->requestBodyBuffering) {
|
479
|
+
doc["body_bytes_buffered"] = (Json::Value::UInt64) req->bodyBytesBuffered;
|
1361
480
|
}
|
1362
|
-
}
|
1363
|
-
|
1364
481
|
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
* clientOutputPipe to the client socket.
|
1370
|
-
*****************************************************/
|
482
|
+
if (req->session != NULL) {
|
483
|
+
Json::Value &sessionDoc = doc["session"] = Json::Value(Json::objectValue);
|
484
|
+
const Session *session = req->session.get();
|
485
|
+
const AppResponse *resp = &req->appResponse;
|
1371
486
|
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
client->logMessage("Disconnecting: client stopped reading prematurely");
|
487
|
+
if (req->session->isClosed()) {
|
488
|
+
sessionDoc["closed"] = true;
|
489
|
+
} else {
|
490
|
+
sessionDoc["pid"] = session->getPid();
|
491
|
+
sessionDoc["gupid"] = session->getGupid().toString();
|
492
|
+
}
|
493
|
+
|
494
|
+
doc["app_response_http_state"] = resp->getHttpStateString();
|
495
|
+
doc["app_response_http_major"] = resp->httpMajor;
|
496
|
+
doc["app_response_http_minor"] = resp->httpMinor;
|
497
|
+
doc["app_response_want_keep_alive"] = resp->wantKeepAlive;
|
498
|
+
doc["app_response_body_type"] = resp->getBodyTypeString();
|
499
|
+
doc["app_response_body_fully_read"] = resp->bodyFullyRead();
|
500
|
+
doc["app_response_body_already_read"] = (Json::Value::UInt64)
|
501
|
+
resp->bodyAlreadyRead;
|
502
|
+
if (resp->httpState != AppResponse::ERROR) {
|
503
|
+
if (resp->bodyType == AppResponse::RBT_CONTENT_LENGTH) {
|
504
|
+
doc["app_response_content_length"] = (Json::Value::UInt64)
|
505
|
+
resp->aux.bodyInfo.contentLength;
|
506
|
+
} else if (resp->bodyType == AppResponse::RBT_CHUNKED) {
|
507
|
+
doc["app_response_end_chunk_reached"] = resp->aux.bodyInfo.endChunkReached;
|
1394
508
|
}
|
1395
|
-
disconnect(client);
|
1396
509
|
} else {
|
1397
|
-
|
510
|
+
doc["parse_error"] = ServerKit::getErrorDesc(resp->aux.parseError);
|
1398
511
|
}
|
1399
|
-
} else {
|
1400
|
-
RH_TRACE(client, 3, "Managed to forward " << ret << " bytes.");
|
1401
|
-
consumed(ret, false);
|
1402
|
-
}
|
1403
|
-
}
|
1404
|
-
|
1405
|
-
void onClientOutputPipeEnd(const ClientPtr &client) {
|
1406
|
-
RH_LOG_EVENT(client, "onClientOutputPipeEnd");
|
1407
|
-
if (!client->connected()) {
|
1408
|
-
return;
|
1409
|
-
}
|
1410
|
-
|
1411
|
-
RH_TRACE(client, 2, "Client output pipe ended; disconnecting client");
|
1412
|
-
client->endScopeLog(&client->scopeLogs.requestProcessing);
|
1413
|
-
disconnect(client);
|
1414
|
-
}
|
1415
|
-
|
1416
|
-
void onClientOutputPipeError(const ClientPtr &client, int errorCode) {
|
1417
|
-
RH_LOG_EVENT(client, "onClientOutputPipeError");
|
1418
|
-
if (!client->connected()) {
|
1419
|
-
return;
|
1420
512
|
}
|
1421
513
|
|
1422
|
-
|
1423
|
-
message << "client output pipe error: ";
|
1424
|
-
message << strerror(errorCode);
|
1425
|
-
message << " (errno=" << errorCode << ")";
|
1426
|
-
disconnectWithError(client, message.str());
|
1427
|
-
}
|
1428
|
-
|
1429
|
-
void onClientOutputWritable(const ClientPtr &client) {
|
1430
|
-
RH_LOG_EVENT(client, "onClientOutputWritable");
|
1431
|
-
if (!client->connected()) {
|
1432
|
-
return;
|
1433
|
-
}
|
1434
|
-
|
1435
|
-
// Continue forwarding output data to the client.
|
1436
|
-
RH_TRACE(client, 3, "Client socket became writable again.");
|
1437
|
-
client->clientOutputWatcher.stop();
|
1438
|
-
assert(!client->clientOutputPipe->isStarted());
|
1439
|
-
client->clientOutputPipe->start();
|
1440
|
-
}
|
1441
|
-
|
1442
|
-
|
1443
|
-
/*****************************************************
|
1444
|
-
* COMPONENT: client acceptor
|
1445
|
-
*
|
1446
|
-
* The following code accepts new client connections
|
1447
|
-
* and forwards events to the appropriate functions
|
1448
|
-
* depending on the client state.
|
1449
|
-
*****************************************************/
|
1450
|
-
|
1451
|
-
FileDescriptor acceptNonBlockingSocket(int sock) {
|
1452
|
-
union {
|
1453
|
-
struct sockaddr_in inaddr;
|
1454
|
-
struct sockaddr_un unaddr;
|
1455
|
-
} u;
|
1456
|
-
socklen_t addrlen = sizeof(u);
|
1457
|
-
|
1458
|
-
if (accept4Available) {
|
1459
|
-
FileDescriptor fd(callAccept4(requestSocket,
|
1460
|
-
(struct sockaddr *) &u, &addrlen, O_NONBLOCK));
|
1461
|
-
// FreeBSD returns EINVAL if accept4() is called with invalid flags.
|
1462
|
-
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
|
1463
|
-
accept4Available = false;
|
1464
|
-
return acceptNonBlockingSocket(sock);
|
1465
|
-
} else {
|
1466
|
-
return fd;
|
1467
|
-
}
|
1468
|
-
} else {
|
1469
|
-
FileDescriptor fd(syscalls::accept(requestSocket,
|
1470
|
-
(struct sockaddr *) &u, &addrlen));
|
1471
|
-
if (fd != -1) {
|
1472
|
-
int e = errno;
|
1473
|
-
setNonBlocking(fd);
|
1474
|
-
errno = e;
|
1475
|
-
}
|
1476
|
-
return fd;
|
1477
|
-
}
|
1478
|
-
}
|
1479
|
-
|
1480
|
-
|
1481
|
-
void onResumeSocketWatcher(ev::timer &timer, int revents) {
|
1482
|
-
P_INFO("Resuming listening on server socket.");
|
1483
|
-
resumeSocketWatcherTimer.stop();
|
1484
|
-
requestSocketWatcher.start();
|
1485
|
-
}
|
1486
|
-
|
1487
|
-
void onAcceptable(ev::io &io, int revents) {
|
1488
|
-
bool endReached = false;
|
1489
|
-
unsigned int count = 0;
|
1490
|
-
unsigned int maxAcceptTries = clamp<unsigned int>(clients.size(), 1, 10);
|
1491
|
-
ClientPtr acceptedClients[10];
|
1492
|
-
|
1493
|
-
while (!endReached && count < maxAcceptTries) {
|
1494
|
-
FileDescriptor fd = acceptNonBlockingSocket(requestSocket);
|
1495
|
-
if (fd == -1) {
|
1496
|
-
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
1497
|
-
endReached = true;
|
1498
|
-
} else {
|
1499
|
-
int e = errno;
|
1500
|
-
P_ERROR("Cannot accept client: " << strerror(e) <<
|
1501
|
-
" (errno=" << e << "). " <<
|
1502
|
-
"Pausing listening on server socket for 3 seconds. " <<
|
1503
|
-
"Current client count: " << clients.size());
|
1504
|
-
requestSocketWatcher.stop();
|
1505
|
-
resumeSocketWatcherTimer.start();
|
1506
|
-
endReached = true;
|
1507
|
-
}
|
1508
|
-
} else if (benchmarkPoint == BP_AFTER_ACCEPT) {
|
1509
|
-
writeExact(fd,
|
1510
|
-
"HTTP/1.1 200 OK\r\n"
|
1511
|
-
"Status: 200 OK\r\n"
|
1512
|
-
"Content-Type: text/html\r\n"
|
1513
|
-
"Connection: close\r\n"
|
1514
|
-
"\r\n"
|
1515
|
-
"Benchmark point: after_accept\n");
|
1516
|
-
} else {
|
1517
|
-
ClientPtr client = boost::make_shared<Client>();
|
1518
|
-
client->associate(this, fd);
|
1519
|
-
clients.insert(make_pair((int) fd, client));
|
1520
|
-
acceptedClients[count] = client;
|
1521
|
-
count++;
|
1522
|
-
RH_DEBUG(client, "New client accepted; new client count = " << clients.size());
|
1523
|
-
}
|
1524
|
-
}
|
1525
|
-
|
1526
|
-
for (unsigned int i = 0; i < count; i++) {
|
1527
|
-
acceptedClients[i]->clientInput->readNow();
|
1528
|
-
}
|
1529
|
-
|
1530
|
-
if (OXT_LIKELY(!clients.empty())) {
|
1531
|
-
inactivityTimer.stop();
|
1532
|
-
}
|
1533
|
-
}
|
1534
|
-
|
1535
|
-
|
1536
|
-
size_t onClientInputData(const ClientPtr &client, const StaticString &data) {
|
1537
|
-
RH_LOG_EVENT(client, "onClientInputData");
|
1538
|
-
if (!client->connected()) {
|
1539
|
-
return 0;
|
1540
|
-
}
|
1541
|
-
|
1542
|
-
if (data.empty()) {
|
1543
|
-
onClientEof(client);
|
1544
|
-
return 0;
|
1545
|
-
} else {
|
1546
|
-
return onClientRealData(client, data.data(), data.size());
|
1547
|
-
}
|
1548
|
-
}
|
1549
|
-
|
1550
|
-
size_t onClientRealData(const ClientPtr &client, const char *buf, size_t size) {
|
1551
|
-
size_t consumed = 0;
|
1552
|
-
|
1553
|
-
while (consumed < size && client->connected() && client->clientInput->isStarted()) {
|
1554
|
-
const char *data = buf + consumed;
|
1555
|
-
size_t len = size - consumed;
|
1556
|
-
size_t locallyConsumed;
|
1557
|
-
|
1558
|
-
RH_TRACE(client, 3, "Processing client data: \"" << cEscapeString(StaticString(data, len)) << "\"");
|
1559
|
-
switch (client->state) {
|
1560
|
-
case Client::BEGIN_READING_CONNECT_PASSWORD:
|
1561
|
-
locallyConsumed = state_beginReadingConnectPassword_onClientData(client, data, len);
|
1562
|
-
break;
|
1563
|
-
case Client::STILL_READING_CONNECT_PASSWORD:
|
1564
|
-
locallyConsumed = state_stillReadingConnectPassword_onClientData(client, data, len);
|
1565
|
-
break;
|
1566
|
-
case Client::READING_HEADER:
|
1567
|
-
locallyConsumed = state_readingHeader_onClientData(client, data, len);
|
1568
|
-
break;
|
1569
|
-
case Client::BUFFERING_REQUEST_BODY:
|
1570
|
-
locallyConsumed = state_bufferingRequestBody_onClientData(client, data, len);
|
1571
|
-
break;
|
1572
|
-
case Client::FORWARDING_BODY_TO_APP:
|
1573
|
-
locallyConsumed = state_forwardingBodyToApp_onClientData(client, data, len);
|
1574
|
-
break;
|
1575
|
-
default:
|
1576
|
-
abort();
|
1577
|
-
}
|
1578
|
-
|
1579
|
-
consumed += locallyConsumed;
|
1580
|
-
RH_TRACE(client, 3, "Processed client data: consumed " << locallyConsumed << " bytes");
|
1581
|
-
assert(consumed <= size);
|
1582
|
-
}
|
1583
|
-
|
1584
|
-
return consumed;
|
1585
|
-
}
|
1586
|
-
|
1587
|
-
void onClientEof(const ClientPtr &client) {
|
1588
|
-
RH_LOG_EVENT(client, "onClientEof; client sent EOF");
|
1589
|
-
switch (client->state) {
|
1590
|
-
case Client::BUFFERING_REQUEST_BODY:
|
1591
|
-
state_bufferingRequestBody_onClientEof(client);
|
1592
|
-
break;
|
1593
|
-
case Client::FORWARDING_BODY_TO_APP:
|
1594
|
-
state_forwardingBodyToApp_onClientEof(client);
|
1595
|
-
break;
|
1596
|
-
default:
|
1597
|
-
disconnect(client);
|
1598
|
-
break;
|
1599
|
-
}
|
1600
|
-
}
|
1601
|
-
|
1602
|
-
void onClientInputError(const ClientPtr &client, const char *message, int errnoCode) {
|
1603
|
-
RH_LOG_EVENT(client, "onClientInputError");
|
1604
|
-
if (!client->connected()) {
|
1605
|
-
return;
|
1606
|
-
}
|
1607
|
-
|
1608
|
-
if (errnoCode == ECONNRESET) {
|
1609
|
-
// We might as well treat ECONNRESET like an EOF.
|
1610
|
-
// http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket
|
1611
|
-
RH_TRACE(client, 3, "Client socket ECONNRESET error; treating it as EOF");
|
1612
|
-
onClientEof(client);
|
1613
|
-
} else {
|
1614
|
-
stringstream message;
|
1615
|
-
message << "client socket read error: ";
|
1616
|
-
message << strerror(errnoCode);
|
1617
|
-
message << " (errno=" << errnoCode << ")";
|
1618
|
-
disconnectWithError(client, message.str());
|
1619
|
-
}
|
1620
|
-
}
|
1621
|
-
|
1622
|
-
|
1623
|
-
void onClientBodyBufferData(const ClientPtr &client, const char *data, size_t size, const FileBackedPipe::ConsumeCallback &consumed) {
|
1624
|
-
RH_LOG_EVENT(client, "onClientBodyBufferData");
|
1625
|
-
if (!client->connected()) {
|
1626
|
-
return;
|
1627
|
-
}
|
1628
|
-
|
1629
|
-
switch (client->state) {
|
1630
|
-
case Client::FORWARDING_BODY_TO_APP:
|
1631
|
-
state_forwardingBodyToApp_onClientBodyBufferData(client, data, size, consumed);
|
1632
|
-
break;
|
1633
|
-
default:
|
1634
|
-
abort();
|
1635
|
-
}
|
1636
|
-
}
|
1637
|
-
|
1638
|
-
void onClientBodyBufferError(const ClientPtr &client, int errorCode) {
|
1639
|
-
RH_LOG_EVENT(client, "onClientBodyBufferError");
|
1640
|
-
if (!client->connected()) {
|
1641
|
-
return;
|
1642
|
-
}
|
1643
|
-
|
1644
|
-
stringstream message;
|
1645
|
-
message << "client body buffer error: ";
|
1646
|
-
message << strerror(errorCode);
|
1647
|
-
message << " (errno=" << errorCode << ")";
|
1648
|
-
disconnectWithError(client, message.str());
|
1649
|
-
}
|
1650
|
-
|
1651
|
-
void onClientBodyBufferEnd(const ClientPtr &client) {
|
1652
|
-
RH_LOG_EVENT(client, "onClientBodyBufferEnd");
|
1653
|
-
if (!client->connected()) {
|
1654
|
-
return;
|
1655
|
-
}
|
1656
|
-
|
1657
|
-
switch (client->state) {
|
1658
|
-
case Client::FORWARDING_BODY_TO_APP:
|
1659
|
-
state_forwardingBodyToApp_onClientBodyBufferEnd(client);
|
1660
|
-
break;
|
1661
|
-
default:
|
1662
|
-
abort();
|
1663
|
-
}
|
1664
|
-
}
|
1665
|
-
|
1666
|
-
void onClientBodyBufferCommit(const ClientPtr &client) {
|
1667
|
-
RH_LOG_EVENT(client, "onClientBodyBufferCommit");
|
1668
|
-
if (!client->connected()) {
|
1669
|
-
return;
|
1670
|
-
}
|
1671
|
-
|
1672
|
-
switch (client->state) {
|
1673
|
-
case Client::BUFFERING_REQUEST_BODY:
|
1674
|
-
state_bufferingRequestBody_onClientBodyBufferCommit(client);
|
1675
|
-
break;
|
1676
|
-
default:
|
1677
|
-
abort();
|
1678
|
-
}
|
1679
|
-
}
|
1680
|
-
|
1681
|
-
void onAppOutputWritable(const ClientPtr &client) {
|
1682
|
-
RH_LOG_EVENT(client, "onAppOutputWritable");
|
1683
|
-
if (!client->connected()) {
|
1684
|
-
return;
|
1685
|
-
}
|
1686
|
-
|
1687
|
-
switch (client->state) {
|
1688
|
-
case Client::SENDING_HEADER_TO_APP:
|
1689
|
-
state_sendingHeaderToApp_onAppOutputWritable(client);
|
1690
|
-
break;
|
1691
|
-
case Client::FORWARDING_BODY_TO_APP:
|
1692
|
-
state_forwardingBodyToApp_onAppOutputWritable(client);
|
1693
|
-
break;
|
1694
|
-
default:
|
1695
|
-
abort();
|
1696
|
-
}
|
1697
|
-
}
|
1698
|
-
|
1699
|
-
|
1700
|
-
void onTimeout(const ClientPtr &client) {
|
1701
|
-
RH_LOG_EVENT(client, "onTimeout");
|
1702
|
-
if (!client->connected()) {
|
1703
|
-
return;
|
1704
|
-
}
|
1705
|
-
|
1706
|
-
switch (client->state) {
|
1707
|
-
case Client::BEGIN_READING_CONNECT_PASSWORD:
|
1708
|
-
case Client::STILL_READING_CONNECT_PASSWORD:
|
1709
|
-
disconnectWithError(client, "no connect password received within timeout");
|
1710
|
-
break;
|
1711
|
-
default:
|
1712
|
-
disconnectWithError(client, "timeout");
|
1713
|
-
break;
|
1714
|
-
}
|
1715
|
-
}
|
1716
|
-
|
1717
|
-
|
1718
|
-
/*****************************************************
|
1719
|
-
* COMPONENT: client -> application plumbing
|
1720
|
-
*
|
1721
|
-
* The following code implements forwarding data from
|
1722
|
-
* the client to the application. Code is seperated
|
1723
|
-
* by client state.
|
1724
|
-
*****************************************************/
|
1725
|
-
|
1726
|
-
|
1727
|
-
/******* State: BEGIN_READING_CONNECT_PASSWORD *******/
|
1728
|
-
|
1729
|
-
void checkConnectPassword(const ClientPtr &client, const char *data, unsigned int len) {
|
1730
|
-
RH_TRACE(client, 3, "Given connect password: \"" << cEscapeString(StaticString(data, len)) << "\"");
|
1731
|
-
if (constantTimeCompare(StaticString(data, len), options.requestSocketPassword)) {
|
1732
|
-
RH_TRACE(client, 3, "Connect password is correct; reading header");
|
1733
|
-
client->state = Client::READING_HEADER;
|
1734
|
-
client->freeBufferedConnectPassword();
|
1735
|
-
client->timeoutTimer.stop();
|
1736
|
-
|
1737
|
-
if (benchmarkPoint == BP_AFTER_CHECK_CONNECT_PASSWORD) {
|
1738
|
-
writeSimpleResponse(client, "Benchmark point: after_check_connect_password\n");
|
1739
|
-
}
|
1740
|
-
} else {
|
1741
|
-
disconnectWithError(client, "wrong connect password");
|
1742
|
-
}
|
1743
|
-
}
|
1744
|
-
|
1745
|
-
size_t state_beginReadingConnectPassword_onClientData(const ClientPtr &client, const char *data, size_t size) {
|
1746
|
-
if (size >= options.requestSocketPassword.size()) {
|
1747
|
-
checkConnectPassword(client, data, options.requestSocketPassword.size());
|
1748
|
-
return options.requestSocketPassword.size();
|
1749
|
-
} else {
|
1750
|
-
client->bufferedConnectPassword.data = (char *) malloc(options.requestSocketPassword.size());
|
1751
|
-
client->bufferedConnectPassword.alreadyRead = size;
|
1752
|
-
memcpy(client->bufferedConnectPassword.data, data, size);
|
1753
|
-
client->state = Client::STILL_READING_CONNECT_PASSWORD;
|
1754
|
-
return size;
|
1755
|
-
}
|
1756
|
-
}
|
1757
|
-
|
1758
|
-
|
1759
|
-
/******* State: STILL_READING_CONNECT_PASSWORD *******/
|
1760
|
-
|
1761
|
-
size_t state_stillReadingConnectPassword_onClientData(const ClientPtr &client, const char *data, size_t size) {
|
1762
|
-
size_t consumed = std::min<size_t>(size,
|
1763
|
-
options.requestSocketPassword.size() -
|
1764
|
-
client->bufferedConnectPassword.alreadyRead);
|
1765
|
-
memcpy(client->bufferedConnectPassword.data + client->bufferedConnectPassword.alreadyRead,
|
1766
|
-
data, consumed);
|
1767
|
-
client->bufferedConnectPassword.alreadyRead += consumed;
|
1768
|
-
if (client->bufferedConnectPassword.alreadyRead == options.requestSocketPassword.size()) {
|
1769
|
-
checkConnectPassword(client, client->bufferedConnectPassword.data,
|
1770
|
-
options.requestSocketPassword.size());
|
1771
|
-
}
|
1772
|
-
return consumed;
|
1773
|
-
}
|
1774
|
-
|
1775
|
-
|
1776
|
-
/******* State: READING_HEADER *******/
|
1777
|
-
|
1778
|
-
bool modifyClientHeaders(const ClientPtr &client) {
|
1779
|
-
ScgiRequestParser &parser = client->scgiParser;
|
1780
|
-
ScgiRequestParser::HeaderMap &map = parser.getMap();
|
1781
|
-
ScgiRequestParser::iterator it, end = map.end();
|
1782
|
-
bool modified = false;
|
1783
|
-
|
1784
|
-
/* The Rack spec specifies that HTTP_CONTENT_LENGTH and HTTP_CONTENT_TYPE must
|
1785
|
-
* not exist and that their respective non-HTTP_ versions should exist instead.
|
1786
|
-
*/
|
1787
|
-
|
1788
|
-
if ((it = map.find("HTTP_CONTENT_LENGTH")) != end) {
|
1789
|
-
if (map.find("CONTENT_LENGTH") == end) {
|
1790
|
-
map["CONTENT_LENGTH"] = it->second;
|
1791
|
-
map.erase("HTTP_CONTENT_LENGTH");
|
1792
|
-
} else {
|
1793
|
-
map.erase(it);
|
1794
|
-
}
|
1795
|
-
modified = true;
|
1796
|
-
}
|
1797
|
-
|
1798
|
-
if ((it = map.find("HTTP_CONTENT_TYPE")) != end) {
|
1799
|
-
if (map.find("CONTENT_TYPE") == end) {
|
1800
|
-
map["CONTENT_TYPE"] = it->second;
|
1801
|
-
map.erase("HTTP_CONTENT_TYPE");
|
1802
|
-
} else {
|
1803
|
-
map.erase(it);
|
1804
|
-
}
|
1805
|
-
modified = true;
|
1806
|
-
}
|
1807
|
-
|
1808
|
-
return modified;
|
1809
|
-
}
|
1810
|
-
|
1811
|
-
void reportBadRequestAndDisconnect(const ClientPtr &client, const char *message) {
|
1812
|
-
writeSimpleResponse(client, message, 400);
|
1813
|
-
if (client->connected()) {
|
1814
|
-
disconnectWithError(client, message);
|
1815
|
-
}
|
1816
|
-
}
|
1817
|
-
|
1818
|
-
void checkAndInternalizeRequestHeaders(const ClientPtr &client) {
|
1819
|
-
ScgiRequestParser &parser = client->scgiParser;
|
1820
|
-
StaticString requestMethod = parser.getHeader("REQUEST_METHOD");
|
1821
|
-
|
1822
|
-
if (requestMethod.empty()) {
|
1823
|
-
reportBadRequestAndDisconnect(client, "Bad request (no request method given)");
|
1824
|
-
return;
|
1825
|
-
}
|
1826
|
-
|
1827
|
-
// Check Content-Length and Transfer-Encoding.
|
1828
|
-
long long contentLength = getULongLongOption(client, "CONTENT_LENGTH");
|
1829
|
-
StaticString transferEncoding = parser.getHeader("HTTP_TRANSFER_ENCODING");
|
1830
|
-
if (contentLength != -1 && !transferEncoding.empty()) {
|
1831
|
-
reportBadRequestAndDisconnect(client, "Bad request (request may not contain both Content-Length and Transfer-Encoding)");
|
1832
|
-
return;
|
1833
|
-
}
|
1834
|
-
if (!transferEncoding.empty() && transferEncoding != "chunked") {
|
1835
|
-
reportBadRequestAndDisconnect(client, "Bad request (only Transfer-Encoding chunked is supported)");
|
1836
|
-
return;
|
1837
|
-
}
|
1838
|
-
// According to the HTTP/1.1 spec, Content-Length may not be 0.
|
1839
|
-
// We could reject the request, but some important HTTP clients are broken
|
1840
|
-
// (*cough* Ruby Net::HTTP *cough*) and fixing them is too much of
|
1841
|
-
// a pain, so we choose support it.
|
1842
|
-
if (contentLength == 0) {
|
1843
|
-
contentLength = -1;
|
1844
|
-
assert(transferEncoding.empty());
|
1845
|
-
}
|
1846
|
-
|
1847
|
-
StaticString upgrade = parser.getHeader("HTTP_UPGRADE");
|
1848
|
-
const bool requestIsGetOrHead = requestMethod == "GET" || requestMethod == "HEAD";
|
1849
|
-
const bool requestBodyOffered = contentLength != -1 || !transferEncoding.empty();
|
1850
|
-
|
1851
|
-
// Reject requests that have a request body and an Upgrade header.
|
1852
|
-
if (!requestIsGetOrHead && !upgrade.empty()) {
|
1853
|
-
reportBadRequestAndDisconnect(client, "Bad request (Upgrade header is only allowed for non-GET and non-HEAD requests)");
|
1854
|
-
return;
|
1855
|
-
}
|
1856
|
-
|
1857
|
-
if (!requestBodyOffered) {
|
1858
|
-
if (upgrade.empty()) {
|
1859
|
-
client->requestBodyLength = 0;
|
1860
|
-
} else {
|
1861
|
-
client->requestBodyLength = -1;
|
1862
|
-
}
|
1863
|
-
} else {
|
1864
|
-
client->requestBodyLength = contentLength;
|
1865
|
-
client->requestIsChunked = !transferEncoding.empty();
|
1866
|
-
}
|
1867
|
-
}
|
1868
|
-
|
1869
|
-
static void fillPoolOption(const ClientPtr &client, StaticString &field, const StaticString &name) {
|
1870
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
1871
|
-
if (it != client->scgiParser.end()) {
|
1872
|
-
field = it->second;
|
1873
|
-
}
|
1874
|
-
}
|
1875
|
-
|
1876
|
-
static void fillPoolOption(const ClientPtr &client, bool &field, const StaticString &name) {
|
1877
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
1878
|
-
if (it != client->scgiParser.end()) {
|
1879
|
-
field = it->second == "true";
|
1880
|
-
}
|
1881
|
-
}
|
1882
|
-
|
1883
|
-
static void fillPoolOption(const ClientPtr &client, unsigned int &field, const StaticString &name) {
|
1884
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
1885
|
-
if (it != client->scgiParser.end()) {
|
1886
|
-
field = stringToUint(it->second);
|
1887
|
-
}
|
1888
|
-
}
|
1889
|
-
|
1890
|
-
static void fillPoolOption(const ClientPtr &client, unsigned long &field, const StaticString &name) {
|
1891
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
1892
|
-
if (it != client->scgiParser.end()) {
|
1893
|
-
field = stringToUint(it->second);
|
1894
|
-
}
|
1895
|
-
}
|
1896
|
-
|
1897
|
-
static void fillPoolOption(const ClientPtr &client, long &field, const StaticString &name) {
|
1898
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
1899
|
-
if (it != client->scgiParser.end()) {
|
1900
|
-
field = stringToInt(it->second);
|
1901
|
-
}
|
1902
|
-
}
|
1903
|
-
|
1904
|
-
static void fillPoolOptionSecToMsec(const ClientPtr &client, unsigned int &field, const StaticString &name) {
|
1905
|
-
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
|
1906
|
-
if (it != client->scgiParser.end()) {
|
1907
|
-
field = stringToUint(it->second) * 1000;
|
1908
|
-
}
|
1909
|
-
}
|
1910
|
-
|
1911
|
-
void fillPoolOptions(const ClientPtr &client) {
|
1912
|
-
Options &options = client->options;
|
1913
|
-
ScgiRequestParser &parser = client->scgiParser;
|
1914
|
-
ScgiRequestParser::const_iterator it, end = client->scgiParser.end();
|
1915
|
-
|
1916
|
-
options = Options();
|
1917
|
-
|
1918
|
-
StaticString scriptName = parser.getHeader("SCRIPT_NAME");
|
1919
|
-
StaticString appRoot = parser.getHeader("PASSENGER_APP_ROOT");
|
1920
|
-
if (scriptName.empty()) {
|
1921
|
-
if (appRoot.empty()) {
|
1922
|
-
StaticString documentRoot = parser.getHeader("DOCUMENT_ROOT");
|
1923
|
-
if (documentRoot.empty()) {
|
1924
|
-
disconnectWithError(client, "no PASSENGER_APP_ROOT or DOCUMENT_ROOT headers set.");
|
1925
|
-
return;
|
1926
|
-
}
|
1927
|
-
client->appRoot = extractDirName(documentRoot);
|
1928
|
-
options.appRoot = client->appRoot;
|
1929
|
-
} else {
|
1930
|
-
options.appRoot = appRoot;
|
1931
|
-
}
|
1932
|
-
} else {
|
1933
|
-
if (appRoot.empty()) {
|
1934
|
-
client->appRoot = extractDirName(resolveSymlink(parser.getHeader("DOCUMENT_ROOT")));
|
1935
|
-
options.appRoot = client->appRoot;
|
1936
|
-
} else {
|
1937
|
-
options.appRoot = appRoot;
|
1938
|
-
}
|
1939
|
-
options.baseURI = scriptName;
|
1940
|
-
}
|
1941
|
-
|
1942
|
-
options.ruby = this->options.defaultRubyCommand;
|
1943
|
-
options.logLevel = getLogLevel();
|
1944
|
-
options.loggingAgentAddress = this->options.loggingAgentAddress;
|
1945
|
-
options.loggingAgentUsername = "logging";
|
1946
|
-
options.loggingAgentPassword = this->options.loggingAgentPassword;
|
1947
|
-
options.defaultUser = this->options.defaultUser;
|
1948
|
-
options.defaultGroup = this->options.defaultGroup;
|
1949
|
-
fillPoolOption(client, options.appGroupName, "PASSENGER_APP_GROUP_NAME");
|
1950
|
-
fillPoolOption(client, options.appType, "PASSENGER_APP_TYPE");
|
1951
|
-
fillPoolOption(client, options.environment, "PASSENGER_APP_ENV");
|
1952
|
-
fillPoolOption(client, options.ruby, "PASSENGER_RUBY");
|
1953
|
-
fillPoolOption(client, options.python, "PASSENGER_PYTHON");
|
1954
|
-
fillPoolOption(client, options.nodejs, "PASSENGER_NODEJS");
|
1955
|
-
fillPoolOption(client, options.user, "PASSENGER_USER");
|
1956
|
-
fillPoolOption(client, options.group, "PASSENGER_GROUP");
|
1957
|
-
fillPoolOption(client, options.minProcesses, "PASSENGER_MIN_PROCESSES");
|
1958
|
-
fillPoolOption(client, options.maxProcesses, "PASSENGER_MAX_PROCESSES");
|
1959
|
-
fillPoolOption(client, options.maxRequests, "PASSENGER_MAX_REQUESTS");
|
1960
|
-
fillPoolOption(client, options.spawnMethod, "PASSENGER_SPAWN_METHOD");
|
1961
|
-
fillPoolOption(client, options.startCommand, "PASSENGER_START_COMMAND");
|
1962
|
-
fillPoolOptionSecToMsec(client, options.startTimeout, "PASSENGER_START_TIMEOUT");
|
1963
|
-
fillPoolOption(client, options.maxPreloaderIdleTime, "PASSENGER_MAX_PRELOADER_IDLE_TIME");
|
1964
|
-
fillPoolOption(client, options.maxRequestQueueSize, "PASSENGER_MAX_REQUEST_QUEUE_SIZE");
|
1965
|
-
fillPoolOption(client, options.statThrottleRate, "PASSENGER_STAT_THROTTLE_RATE");
|
1966
|
-
fillPoolOption(client, options.restartDir, "PASSENGER_RESTART_DIR");
|
1967
|
-
fillPoolOption(client, options.startupFile, "PASSENGER_STARTUP_FILE");
|
1968
|
-
fillPoolOption(client, options.loadShellEnvvars, "PASSENGER_LOAD_SHELL_ENVVARS");
|
1969
|
-
fillPoolOption(client, options.debugger, "PASSENGER_DEBUGGER");
|
1970
|
-
fillPoolOption(client, options.raiseInternalError, "PASSENGER_RAISE_INTERNAL_ERROR");
|
1971
|
-
setStickySessionId(client);
|
1972
|
-
/******************/
|
1973
|
-
|
1974
|
-
for (it = client->scgiParser.begin(); it != end; it++) {
|
1975
|
-
if (!startsWith(it->first, "PASSENGER_")
|
1976
|
-
&& !startsWith(it->first, "HTTP_")
|
1977
|
-
&& it->first != "PATH_INFO"
|
1978
|
-
&& it->first != "SCRIPT_NAME"
|
1979
|
-
&& it->first != "CONTENT_LENGTH"
|
1980
|
-
&& it->first != "CONTENT_TYPE")
|
1981
|
-
{
|
1982
|
-
options.environmentVariables.push_back(*it);
|
1983
|
-
}
|
1984
|
-
}
|
1985
|
-
}
|
1986
|
-
|
1987
|
-
void initializeUnionStation(const ClientPtr &client) {
|
1988
|
-
if (getBoolOption(client, "UNION_STATION_SUPPORT", false)) {
|
1989
|
-
Options &options = client->options;
|
1990
|
-
ScgiRequestParser &parser = client->scgiParser;
|
1991
|
-
|
1992
|
-
StaticString key = parser.getHeader("UNION_STATION_KEY");
|
1993
|
-
StaticString filters = parser.getHeader("UNION_STATION_FILTERS");
|
1994
|
-
if (key.empty()) {
|
1995
|
-
disconnectWithError(client, "header UNION_STATION_KEY must be set.");
|
1996
|
-
return;
|
1997
|
-
}
|
1998
|
-
|
1999
|
-
client->options.transaction = unionStationCore->newTransaction(
|
2000
|
-
options.getAppGroupName(), "requests", key, filters);
|
2001
|
-
if (!client->options.transaction->isNull()) {
|
2002
|
-
client->options.analytics = true;
|
2003
|
-
client->options.unionStationKey = key;
|
2004
|
-
}
|
2005
|
-
|
2006
|
-
client->beginScopeLog(&client->scopeLogs.requestProcessing, "request processing");
|
2007
|
-
|
2008
|
-
StaticString staticRequestMethod = parser.getHeader("REQUEST_METHOD");
|
2009
|
-
client->logMessage("Request method: " + staticRequestMethod);
|
2010
|
-
|
2011
|
-
StaticString staticRequestURI = parser.getHeader("REQUEST_URI");
|
2012
|
-
if (!staticRequestURI.empty()) {
|
2013
|
-
client->logMessage("URI: " + staticRequestURI);
|
2014
|
-
} else {
|
2015
|
-
string requestURI = parser.getHeader("SCRIPT_NAME");
|
2016
|
-
requestURI.append(parser.getHeader("PATH_INFO"));
|
2017
|
-
StaticString queryString = parser.getHeader("QUERY_STRING");
|
2018
|
-
if (!queryString.empty()) {
|
2019
|
-
requestURI.append("?");
|
2020
|
-
requestURI.append(queryString);
|
2021
|
-
}
|
2022
|
-
client->logMessage("URI: " + requestURI);
|
2023
|
-
}
|
2024
|
-
}
|
2025
|
-
}
|
2026
|
-
|
2027
|
-
void parseCookieHeader(const StaticString &header,
|
2028
|
-
vector< pair<StaticString, StaticString> > &cookies) const
|
2029
|
-
{
|
2030
|
-
// See http://stackoverflow.com/questions/6108207/definite-guide-to-valid-cookie-values
|
2031
|
-
// for syntax grammar.
|
2032
|
-
vector<StaticString> parts;
|
2033
|
-
vector<StaticString>::const_iterator it, it_end;
|
2034
|
-
|
2035
|
-
split(header, ';', parts);
|
2036
|
-
cookies.reserve(parts.size());
|
2037
|
-
it_end = parts.end();
|
2038
|
-
|
2039
|
-
for (it = parts.begin(); it != it_end; it++) {
|
2040
|
-
const char *begin = it->data();
|
2041
|
-
const char *end = it->data() + it->size();
|
2042
|
-
const char *sep;
|
2043
|
-
|
2044
|
-
skipLeadingWhitespaces(&begin, end);
|
2045
|
-
skipTrailingWhitespaces(begin, &end);
|
2046
|
-
|
2047
|
-
// Find the separator ('=').
|
2048
|
-
sep = (const char *) memchr(begin, '=', end - begin);
|
2049
|
-
if (sep != NULL) {
|
2050
|
-
// Valid cookie. Otherwise, ignore it.
|
2051
|
-
const char *nameEnd = sep;
|
2052
|
-
const char *valueBegin = sep + 1;
|
2053
|
-
|
2054
|
-
skipTrailingWhitespaces(begin, &nameEnd);
|
2055
|
-
skipLeadingWhitespaces(&valueBegin, end);
|
2056
|
-
|
2057
|
-
cookies.push_back(make_pair(
|
2058
|
-
StaticString(begin, nameEnd - begin),
|
2059
|
-
StaticString(valueBegin, end - valueBegin)
|
2060
|
-
));
|
2061
|
-
}
|
2062
|
-
}
|
2063
|
-
}
|
2064
|
-
|
2065
|
-
void setStickySessionId(const ClientPtr &client) {
|
2066
|
-
ScgiRequestParser &parser = client->scgiParser;
|
2067
|
-
if (parser.getHeader("PASSENGER_STICKY_SESSIONS") == "true") {
|
2068
|
-
// TODO: This is not entirely correct. Clients MAY send multiple Cookie
|
2069
|
-
// headers, although this is in practice extremely rare.
|
2070
|
-
// http://stackoverflow.com/questions/16305814/are-multiple-cookie-headers-allowed-in-an-http-request
|
2071
|
-
StaticString cookieHeader = parser.getHeader("HTTP_COOKIE");
|
2072
|
-
StaticString cookieName = getStickySessionCookieName(client);
|
2073
|
-
vector< pair<StaticString, StaticString> > cookies;
|
2074
|
-
pair<StaticString, StaticString> cookie;
|
2075
|
-
|
2076
|
-
client->stickySession = true;
|
2077
|
-
parseCookieHeader(cookieHeader, cookies);
|
2078
|
-
foreach (cookie, cookies) {
|
2079
|
-
if (cookie.first == cookieName) {
|
2080
|
-
// This cookie matches the one we're looking for.
|
2081
|
-
client->options.stickySessionId = stringToUint(cookie.second);
|
2082
|
-
return;
|
2083
|
-
}
|
2084
|
-
}
|
2085
|
-
}
|
2086
|
-
}
|
2087
|
-
|
2088
|
-
StaticString getStickySessionCookieName(const ClientPtr &client) const {
|
2089
|
-
StaticString value = client->scgiParser.getHeader("PASSENGER_STICKY_SESSIONS_COOKIE_NAME");
|
2090
|
-
if (value.empty()) {
|
2091
|
-
return StaticString(DEFAULT_STICKY_SESSIONS_COOKIE_NAME,
|
2092
|
-
sizeof(DEFAULT_STICKY_SESSIONS_COOKIE_NAME) - 1);
|
2093
|
-
} else {
|
2094
|
-
return value;
|
2095
|
-
}
|
2096
|
-
}
|
2097
|
-
|
2098
|
-
size_t state_readingHeader_onClientData(const ClientPtr &client, const char *data, size_t size) {
|
2099
|
-
ScgiRequestParser &parser = client->scgiParser;
|
2100
|
-
size_t consumed = parser.feed(data, size);
|
2101
|
-
if (!parser.acceptingInput()) {
|
2102
|
-
if (parser.getState() == ScgiRequestParser::ERROR) {
|
2103
|
-
if (parser.getErrorReason() == ScgiRequestParser::LIMIT_REACHED) {
|
2104
|
-
disconnectWithError(client, "SCGI header too large");
|
2105
|
-
} else {
|
2106
|
-
disconnectWithError(client, "invalid SCGI header");
|
2107
|
-
}
|
2108
|
-
return consumed;
|
2109
|
-
}
|
2110
|
-
|
2111
|
-
if (benchmarkPoint == BP_AFTER_PARSING_HEADER) {
|
2112
|
-
writeSimpleResponse(client, "Benchmark point: after_parsing_header\n");
|
2113
|
-
return consumed;
|
2114
|
-
}
|
2115
|
-
|
2116
|
-
bool modified = modifyClientHeaders(client);
|
2117
|
-
/* TODO: in case the headers are not modified, we only need to rebuild the header data
|
2118
|
-
* right now because the scgiParser buffer is invalidated as soon as onClientData exits.
|
2119
|
-
* We should figure out a way to not copy anything if we can do everything before
|
2120
|
-
* onClientData exits.
|
2121
|
-
*/
|
2122
|
-
parser.rebuildData(modified);
|
2123
|
-
|
2124
|
-
checkAndInternalizeRequestHeaders(client);
|
2125
|
-
if (!client->connected()) {
|
2126
|
-
return consumed;
|
2127
|
-
}
|
2128
|
-
fillPoolOptions(client);
|
2129
|
-
if (!client->connected()) {
|
2130
|
-
return consumed;
|
2131
|
-
}
|
2132
|
-
initializeUnionStation(client);
|
2133
|
-
if (!client->connected()) {
|
2134
|
-
return consumed;
|
2135
|
-
}
|
2136
|
-
|
2137
|
-
if (getBoolOption(client, "PASSENGER_BUFFERING")) {
|
2138
|
-
RH_TRACE(client, 3, "Valid SCGI header; buffering request body");
|
2139
|
-
client->state = Client::BUFFERING_REQUEST_BODY;
|
2140
|
-
client->requestBodyIsBuffered = true;
|
2141
|
-
client->beginScopeLog(&client->scopeLogs.bufferingRequestBody, "buffering request body");
|
2142
|
-
if (client->requestBodyLength == 0) {
|
2143
|
-
client->clientInput->stop();
|
2144
|
-
state_bufferingRequestBody_onClientEof(client);
|
2145
|
-
return 0;
|
2146
|
-
}
|
2147
|
-
} else {
|
2148
|
-
RH_TRACE(client, 3, "Valid SCGI header; not buffering request body; checking out session");
|
2149
|
-
client->clientInput->stop();
|
2150
|
-
checkoutSession(client);
|
2151
|
-
}
|
2152
|
-
}
|
2153
|
-
return consumed;
|
2154
|
-
}
|
2155
|
-
|
2156
|
-
|
2157
|
-
/******* State: BUFFERING_REQUEST_BODY *******/
|
2158
|
-
|
2159
|
-
void state_bufferingRequestBody_verifyInvariants(const ClientPtr &client) const {
|
2160
|
-
assert(client->requestBodyIsBuffered);
|
2161
|
-
assert(!client->clientBodyBuffer->isStarted());
|
2162
|
-
}
|
2163
|
-
|
2164
|
-
size_t state_bufferingRequestBody_onClientData(const ClientPtr &client, const char *data, size_t size) {
|
2165
|
-
state_bufferingRequestBody_verifyInvariants(client);
|
2166
|
-
assert(!client->clientBodyBuffer->isCommittingToDisk());
|
2167
|
-
|
2168
|
-
if (client->requestBodyLength >= 0) {
|
2169
|
-
size = std::min<unsigned long long>(
|
2170
|
-
size,
|
2171
|
-
(unsigned long long) client->requestBodyLength - client->requestBodyAlreadyRead
|
2172
|
-
);
|
2173
|
-
}
|
2174
|
-
|
2175
|
-
if (!client->clientBodyBuffer->write(data, size)) {
|
2176
|
-
// The pipe cannot write the data to disk quickly enough, so
|
2177
|
-
// suspend reading from the client until the pipe is done.
|
2178
|
-
client->backgroundOperations++; // TODO: figure out whether this is necessary
|
2179
|
-
client->clientInput->stop();
|
2180
|
-
}
|
2181
|
-
client->requestBodyAlreadyRead += size;
|
2182
|
-
|
2183
|
-
RH_TRACE(client, 3, "Buffered " << size << " bytes of client body data; total=" <<
|
2184
|
-
client->requestBodyAlreadyRead << ", content-length=" << client->requestBodyLength);
|
2185
|
-
assert(client->requestBodyLength == -1 || client->requestBodyAlreadyRead <= (unsigned long long) client->requestBodyLength);
|
2186
|
-
|
2187
|
-
if (client->requestBodyLength >= 0 && client->requestBodyAlreadyRead == (unsigned long long) client->requestBodyLength) {
|
2188
|
-
if (client->clientBodyBuffer->isCommittingToDisk()) {
|
2189
|
-
RH_TRACE(client, 3, "Done buffering request body, but clientBodyBuffer not yet done committing data to disk; waiting until it's done");
|
2190
|
-
client->checkoutSessionAfterCommit = true;
|
2191
|
-
} else {
|
2192
|
-
client->clientInput->stop();
|
2193
|
-
state_bufferingRequestBody_onClientEof(client);
|
2194
|
-
}
|
2195
|
-
}
|
2196
|
-
|
2197
|
-
return size;
|
2198
|
-
}
|
2199
|
-
|
2200
|
-
void state_bufferingRequestBody_onClientEof(const ClientPtr &client) {
|
2201
|
-
state_bufferingRequestBody_verifyInvariants(client);
|
2202
|
-
|
2203
|
-
RH_TRACE(client, 3, "Done buffering request body; checking out session");
|
2204
|
-
client->clientBodyBuffer->end();
|
2205
|
-
client->endScopeLog(&client->scopeLogs.bufferingRequestBody);
|
2206
|
-
checkoutSession(client);
|
2207
|
-
}
|
2208
|
-
|
2209
|
-
void state_bufferingRequestBody_onClientBodyBufferCommit(const ClientPtr &client) {
|
2210
|
-
// Now that the pipe has committed the data to disk
|
2211
|
-
// resume reading from the client socket.
|
2212
|
-
state_bufferingRequestBody_verifyInvariants(client);
|
2213
|
-
assert(!client->clientInput->isStarted());
|
2214
|
-
client->backgroundOperations--;
|
2215
|
-
if (client->checkoutSessionAfterCommit) {
|
2216
|
-
RH_TRACE(client, 3, "Done committing request body to disk");
|
2217
|
-
state_bufferingRequestBody_onClientEof(client);
|
2218
|
-
} else {
|
2219
|
-
client->clientInput->start();
|
2220
|
-
}
|
2221
|
-
}
|
2222
|
-
|
2223
|
-
|
2224
|
-
/******* State: CHECKING_OUT_SESSION *******/
|
2225
|
-
|
2226
|
-
void state_checkingOutSession_verifyInvariants(const ClientPtr &client) {
|
2227
|
-
assert(!client->clientInput->isStarted());
|
2228
|
-
assert(!client->clientBodyBuffer->isStarted());
|
2229
|
-
}
|
2230
|
-
|
2231
|
-
void checkoutSession(const ClientPtr &client) {
|
2232
|
-
if (benchmarkPoint != BP_BEFORE_CHECKOUT_SESSION) {
|
2233
|
-
RH_TRACE(client, 2, "Checking out session: appRoot=" << client->options.appRoot);
|
2234
|
-
client->state = Client::CHECKING_OUT_SESSION;
|
2235
|
-
client->beginScopeLog(&client->scopeLogs.getFromPool, "get from pool");
|
2236
|
-
pool->asyncGet(client->options, boost::bind(&RequestHandler::sessionCheckedOut,
|
2237
|
-
this, client, _1, _2));
|
2238
|
-
if (!client->sessionCheckedOut) {
|
2239
|
-
client->backgroundOperations++;
|
2240
|
-
}
|
2241
|
-
} else {
|
2242
|
-
writeSimpleResponse(client, "Benchmark point: before_checkout_session\n");
|
2243
|
-
}
|
2244
|
-
}
|
2245
|
-
|
2246
|
-
void sessionCheckedOut(ClientPtr client, const SessionPtr &session, const ExceptionPtr &e) {
|
2247
|
-
if (!pthread_equal(pthread_self(), libev->getCurrentThread())) {
|
2248
|
-
libev->runLater(boost::bind(&RequestHandler::sessionCheckedOut_real, this,
|
2249
|
-
client, session, e));
|
2250
|
-
} else {
|
2251
|
-
sessionCheckedOut_real(client, session, e);
|
2252
|
-
}
|
2253
|
-
}
|
2254
|
-
|
2255
|
-
void sessionCheckedOut_real(ClientPtr client, const SessionPtr &session, const ExceptionPtr &e) {
|
2256
|
-
RH_LOG_EVENT(client, "sessionCheckedOut");
|
2257
|
-
if (!client->connected()) {
|
2258
|
-
return;
|
2259
|
-
}
|
2260
|
-
|
2261
|
-
state_checkingOutSession_verifyInvariants(client);
|
2262
|
-
client->backgroundOperations--;
|
2263
|
-
client->sessionCheckedOut = true;
|
2264
|
-
|
2265
|
-
if (e != NULL) {
|
2266
|
-
client->endScopeLog(&client->scopeLogs.getFromPool, false);
|
2267
|
-
{
|
2268
|
-
boost::shared_ptr<RequestQueueFullException> e2 = dynamic_pointer_cast<RequestQueueFullException>(e);
|
2269
|
-
if (e2 != NULL) {
|
2270
|
-
writeRequestQueueFullExceptionErrorResponse(client);
|
2271
|
-
return;
|
2272
|
-
}
|
2273
|
-
}
|
2274
|
-
{
|
2275
|
-
boost::shared_ptr<SpawnException> e2 = dynamic_pointer_cast<SpawnException>(e);
|
2276
|
-
if (e2 != NULL) {
|
2277
|
-
writeSpawnExceptionErrorResponse(client, e2);
|
2278
|
-
return;
|
2279
|
-
}
|
2280
|
-
}
|
2281
|
-
writeOtherExceptionErrorResponse(client, e);
|
2282
|
-
} else {
|
2283
|
-
RH_DEBUG(client, "Session checked out: pid=" << session->getPid() <<
|
2284
|
-
", gupid=" << session->getGupid());
|
2285
|
-
client->session = session;
|
2286
|
-
initiateSession(client);
|
2287
|
-
}
|
2288
|
-
}
|
2289
|
-
|
2290
|
-
void writeRequestQueueFullExceptionErrorResponse(const ClientPtr &client) {
|
2291
|
-
StaticString value = client->scgiParser.getHeader("PASSENGER_REQUEST_QUEUE_OVERFLOW_STATUS_CODE");
|
2292
|
-
int requestQueueOverflowStatusCode = 503;
|
2293
|
-
if (!value.empty()) {
|
2294
|
-
requestQueueOverflowStatusCode = atoi(value.data());
|
2295
|
-
}
|
2296
|
-
writeSimpleResponse(client,
|
2297
|
-
"<h1>This website is under heavy load</h1>"
|
2298
|
-
"<p>We're sorry, too many people are accessing this website at the same "
|
2299
|
-
"time. We're working on this problem. Please try again later.</p>",
|
2300
|
-
requestQueueOverflowStatusCode);
|
2301
|
-
}
|
2302
|
-
|
2303
|
-
void writeSpawnExceptionErrorResponse(const ClientPtr &client, const boost::shared_ptr<SpawnException> &e) {
|
2304
|
-
RH_ERROR(client, "Cannot checkout session because a spawning error occurred. " <<
|
2305
|
-
"The identifier of the error is " << e->get("error_id") << ". Please see earlier logs for " <<
|
2306
|
-
"details about the error.");
|
2307
|
-
writeErrorResponse(client, e->getErrorPage(), e.get());
|
2308
|
-
}
|
2309
|
-
|
2310
|
-
void writeOtherExceptionErrorResponse(const ClientPtr &client, const ExceptionPtr &e) {
|
2311
|
-
string typeName;
|
2312
|
-
#ifdef CXX_ABI_API_AVAILABLE
|
2313
|
-
int status;
|
2314
|
-
char *tmp = abi::__cxa_demangle(typeid(*e).name(), 0, 0, &status);
|
2315
|
-
if (tmp != NULL) {
|
2316
|
-
typeName = tmp;
|
2317
|
-
free(tmp);
|
2318
|
-
} else {
|
2319
|
-
typeName = typeid(*e).name();
|
2320
|
-
}
|
2321
|
-
#else
|
2322
|
-
typeName = typeid(*e).name();
|
2323
|
-
#endif
|
2324
|
-
|
2325
|
-
RH_WARN(client, "Cannot checkout session (exception type " <<
|
2326
|
-
typeName << "): " << e->what());
|
2327
|
-
|
2328
|
-
string response = "An internal error occurred while trying to spawn the application.\n";
|
2329
|
-
response.append("Exception type: ");
|
2330
|
-
response.append(typeName);
|
2331
|
-
response.append("\nError message: ");
|
2332
|
-
response.append(e->what());
|
2333
|
-
boost::shared_ptr<tracable_exception> e3 = dynamic_pointer_cast<tracable_exception>(e);
|
2334
|
-
if (e3 != NULL) {
|
2335
|
-
response.append("\nBacktrace:\n");
|
2336
|
-
response.append(e3->backtrace());
|
2337
|
-
}
|
2338
|
-
|
2339
|
-
writeErrorResponse(client, response);
|
2340
|
-
}
|
2341
|
-
|
2342
|
-
void initiateSession(const ClientPtr &client) {
|
2343
|
-
assert(client->state == Client::CHECKING_OUT_SESSION);
|
2344
|
-
client->sessionCheckoutTry++;
|
2345
|
-
try {
|
2346
|
-
client->session->initiate();
|
2347
|
-
} catch (const SystemException &e2) {
|
2348
|
-
if (client->sessionCheckoutTry < 10) {
|
2349
|
-
RH_DEBUG(client, "Error checking out session (" << e2.what() <<
|
2350
|
-
"); retrying (attempt " << client->sessionCheckoutTry << ")");
|
2351
|
-
client->sessionCheckedOut = false;
|
2352
|
-
pool->asyncGet(client->options,
|
2353
|
-
boost::bind(&RequestHandler::sessionCheckedOut,
|
2354
|
-
this, client, _1, _2));
|
2355
|
-
if (!client->sessionCheckedOut) {
|
2356
|
-
client->backgroundOperations++;
|
2357
|
-
}
|
2358
|
-
} else {
|
2359
|
-
string message = "could not initiate a session (";
|
2360
|
-
message.append(e2.what());
|
2361
|
-
message.append(")");
|
2362
|
-
disconnectWithError(client, message);
|
2363
|
-
}
|
2364
|
-
return;
|
2365
|
-
}
|
2366
|
-
|
2367
|
-
if (client->useUnionStation()) {
|
2368
|
-
client->endScopeLog(&client->scopeLogs.getFromPool);
|
2369
|
-
client->logMessage("Application PID: " +
|
2370
|
-
toString(client->session->getPid()) +
|
2371
|
-
" (GUPID: " + client->session->getGupid() + ")");
|
2372
|
-
client->beginScopeLog(&client->scopeLogs.requestProxying, "request proxying");
|
2373
|
-
}
|
2374
|
-
|
2375
|
-
RH_DEBUG(client, "Session initiated: fd=" << client->session->fd());
|
2376
|
-
setNonBlocking(client->session->fd());
|
2377
|
-
client->appInput->reset(libev.get(), client->session->fd());
|
2378
|
-
client->appInput->start();
|
2379
|
-
client->appOutputWatcher.set(libev->getLoop());
|
2380
|
-
client->appOutputWatcher.set(client->session->fd(), ev::WRITE);
|
2381
|
-
sendHeaderToApp(client);
|
2382
|
-
}
|
2383
|
-
|
2384
|
-
|
2385
|
-
/******* State: SENDING_HEADER_TO_APP *******/
|
2386
|
-
|
2387
|
-
void state_sendingHeaderToApp_verifyInvariants(const ClientPtr &client) {
|
2388
|
-
assert(!client->clientInput->isStarted());
|
2389
|
-
assert(!client->clientBodyBuffer->isStarted());
|
2390
|
-
}
|
2391
|
-
|
2392
|
-
void sendHeaderToApp(const ClientPtr &client) {
|
2393
|
-
assert(!client->clientInput->isStarted());
|
2394
|
-
assert(!client->clientBodyBuffer->isStarted());
|
2395
|
-
|
2396
|
-
RH_TRACE(client, 2, "Sending headers to application");
|
2397
|
-
|
2398
|
-
if (client->session == NULL) {
|
2399
|
-
disconnectWithError(client,
|
2400
|
-
"Application sent EOF before we were able to send headers to it");
|
2401
|
-
} else if (client->session->getProtocol() == "session") {
|
2402
|
-
char sizeField[sizeof(boost::uint32_t)];
|
2403
|
-
SmallVector<StaticString, 10> data;
|
2404
|
-
|
2405
|
-
data.push_back(StaticString(sizeField, sizeof(boost::uint32_t)));
|
2406
|
-
data.push_back(client->scgiParser.getHeaderData());
|
2407
|
-
|
2408
|
-
data.push_back(makeStaticStringWithNull("PASSENGER_CONNECT_PASSWORD"));
|
2409
|
-
data.push_back(makeStaticStringWithNull(client->session->getConnectPassword()));
|
2410
|
-
|
2411
|
-
if (client->options.analytics) {
|
2412
|
-
data.push_back(makeStaticStringWithNull("PASSENGER_TXN_ID"));
|
2413
|
-
data.push_back(makeStaticStringWithNull(client->options.transaction->getTxnId()));
|
2414
|
-
}
|
2415
|
-
|
2416
|
-
boost::uint32_t dataSize = 0;
|
2417
|
-
for (unsigned int i = 1; i < data.size(); i++) {
|
2418
|
-
dataSize += (boost::uint32_t) data[i].size();
|
2419
|
-
}
|
2420
|
-
Uint32Message::generate(sizeField, dataSize);
|
2421
|
-
|
2422
|
-
ssize_t ret = gatheredWrite(client->session->fd(), &data[0],
|
2423
|
-
data.size(), client->appOutputBuffer);
|
2424
|
-
if (ret == -1 && errno != EAGAIN) {
|
2425
|
-
disconnectWithAppSocketWriteError(client, errno);
|
2426
|
-
} else if (!client->appOutputBuffer.empty()) {
|
2427
|
-
client->state = Client::SENDING_HEADER_TO_APP;
|
2428
|
-
client->appOutputWatcher.start();
|
2429
|
-
} else {
|
2430
|
-
sendBodyToApp(client);
|
2431
|
-
}
|
2432
|
-
} else {
|
2433
|
-
assert(client->session->getProtocol() == "http_session");
|
2434
|
-
const ScgiRequestParser &parser = client->scgiParser;
|
2435
|
-
ScgiRequestParser::const_iterator it, end = parser.end();
|
2436
|
-
string data;
|
2437
|
-
|
2438
|
-
data.reserve(parser.getHeaderData().size() + 128);
|
2439
|
-
data.append(parser.getHeader("REQUEST_METHOD"));
|
2440
|
-
data.append(" ");
|
2441
|
-
data.append(parser.getHeader("REQUEST_URI"));
|
2442
|
-
data.append(" HTTP/1.1\r\n");
|
2443
|
-
|
2444
|
-
for (it = parser.begin(); it != end; it++) {
|
2445
|
-
if (startsWith(it->first, "HTTP_") && it->first != "HTTP_CONNECTION") {
|
2446
|
-
string subheader = it->first.substr(sizeof("HTTP_") - 1);
|
2447
|
-
string::size_type i;
|
2448
|
-
for (i = 0; i < subheader.size(); i++) {
|
2449
|
-
if (subheader[i] == '_') {
|
2450
|
-
subheader[i] = '-';
|
2451
|
-
} else if (i > 0 && subheader[i - 1] != '-') {
|
2452
|
-
subheader[i] = tolower(subheader[i]);
|
2453
|
-
}
|
2454
|
-
}
|
2455
|
-
|
2456
|
-
data.append(subheader);
|
2457
|
-
data.append(": ");
|
2458
|
-
data.append(it->second);
|
2459
|
-
data.append("\r\n");
|
2460
|
-
}
|
2461
|
-
}
|
2462
|
-
|
2463
|
-
StaticString connection = parser.getHeader("HTTP_CONNECTION");
|
2464
|
-
if (regex_match(connection.data(), connection.data() + connection.size(),
|
2465
|
-
upgradeHeaderRegex))
|
2466
|
-
{
|
2467
|
-
data.append("Connection: ");
|
2468
|
-
data.append(connection.data(), connection.size());
|
2469
|
-
data.append("\r\n");
|
2470
|
-
} else {
|
2471
|
-
data.append("Connection: close\r\n");
|
2472
|
-
}
|
2473
|
-
|
2474
|
-
StaticString header = parser.getHeader("CONTENT_LENGTH");
|
2475
|
-
if (!header.empty()) {
|
2476
|
-
data.append("Content-Length: ");
|
2477
|
-
data.append(header);
|
2478
|
-
data.append("\r\n");
|
2479
|
-
}
|
2480
|
-
|
2481
|
-
header = parser.getHeader("CONTENT_TYPE");
|
2482
|
-
if (!header.empty()) {
|
2483
|
-
data.append("Content-Type: ");
|
2484
|
-
data.append(header);
|
2485
|
-
data.append("\r\n");
|
2486
|
-
}
|
2487
|
-
|
2488
|
-
header = parser.getHeader("HTTPS");
|
2489
|
-
if (!header.empty()) {
|
2490
|
-
data.append("X-Forwarded-Proto: https\r\n");
|
2491
|
-
}
|
2492
|
-
|
2493
|
-
header = parser.getHeader("REMOTE_ADDR");
|
2494
|
-
if (!header.empty()) {
|
2495
|
-
data.append("X-Forwarded-For: ");
|
2496
|
-
data.append(header);
|
2497
|
-
data.append("\r\n");
|
2498
|
-
}
|
2499
|
-
|
2500
|
-
if (client->options.analytics) {
|
2501
|
-
data.append("Passenger-Txn-Id: ");
|
2502
|
-
data.append(client->options.transaction->getTxnId());
|
2503
|
-
data.append("\r\n");
|
2504
|
-
}
|
2505
|
-
|
2506
|
-
P_TRACE(3, "Sending headers to application: " << data);
|
2507
|
-
data.append("\r\n");
|
2508
|
-
|
2509
|
-
StaticString datas[] = { data };
|
2510
|
-
ssize_t ret = gatheredWrite(client->session->fd(), datas,
|
2511
|
-
1, client->appOutputBuffer);
|
2512
|
-
if (ret == -1 && errno != EAGAIN) {
|
2513
|
-
disconnectWithAppSocketWriteError(client, errno);
|
2514
|
-
// TODO: what about other errors?
|
2515
|
-
} else if (!client->appOutputBuffer.empty()) {
|
2516
|
-
client->state = Client::SENDING_HEADER_TO_APP;
|
2517
|
-
client->appOutputWatcher.start();
|
2518
|
-
} else {
|
2519
|
-
sendBodyToApp(client);
|
2520
|
-
}
|
2521
|
-
}
|
2522
|
-
}
|
2523
|
-
|
2524
|
-
void state_sendingHeaderToApp_onAppOutputWritable(const ClientPtr &client) {
|
2525
|
-
state_sendingHeaderToApp_verifyInvariants(client);
|
2526
|
-
|
2527
|
-
if (client->session == NULL) {
|
2528
|
-
disconnectWithError(client,
|
2529
|
-
"Application sent EOF before we were able to send headers to it");
|
2530
|
-
} else {
|
2531
|
-
ssize_t ret = gatheredWrite(client->session->fd(), NULL, 0, client->appOutputBuffer);
|
2532
|
-
if (ret == -1) {
|
2533
|
-
if (errno != EAGAIN && errno != EPIPE && errno != ECONNRESET) {
|
2534
|
-
disconnectWithAppSocketWriteError(client, errno);
|
2535
|
-
}
|
2536
|
-
// TODO: what about other errors?
|
2537
|
-
} else if (client->appOutputBuffer.empty()) {
|
2538
|
-
client->appOutputWatcher.stop();
|
2539
|
-
sendBodyToApp(client);
|
2540
|
-
}
|
2541
|
-
}
|
2542
|
-
}
|
2543
|
-
|
2544
|
-
|
2545
|
-
/******* State: FORWARDING_BODY_TO_APP *******/
|
2546
|
-
|
2547
|
-
void state_forwardingBodyToApp_verifyInvariants(const ClientPtr &client) const {
|
2548
|
-
assert(client->state == Client::FORWARDING_BODY_TO_APP);
|
2549
|
-
}
|
2550
|
-
|
2551
|
-
void sendBodyToApp(const ClientPtr &client) {
|
2552
|
-
assert(client->appOutputBuffer.empty());
|
2553
|
-
assert(!client->clientBodyBuffer->isStarted());
|
2554
|
-
assert(!client->clientInput->isStarted());
|
2555
|
-
assert(!client->appOutputWatcher.is_active());
|
2556
|
-
|
2557
|
-
RH_TRACE(client, 2, "Begin sending body to application");
|
2558
|
-
|
2559
|
-
client->state = Client::FORWARDING_BODY_TO_APP;
|
2560
|
-
if (client->requestBodyIsBuffered) {
|
2561
|
-
client->clientBodyBuffer->start();
|
2562
|
-
} else if (client->requestBodyLength == 0) {
|
2563
|
-
state_forwardingBodyToApp_onClientEof(client);
|
2564
|
-
} else {
|
2565
|
-
client->clientInput->start();
|
2566
|
-
}
|
2567
|
-
}
|
2568
|
-
|
2569
|
-
|
2570
|
-
size_t state_forwardingBodyToApp_onClientData(const ClientPtr &client,
|
2571
|
-
const char *data, size_t size)
|
2572
|
-
{
|
2573
|
-
state_forwardingBodyToApp_verifyInvariants(client);
|
2574
|
-
assert(!client->requestBodyIsBuffered);
|
2575
|
-
|
2576
|
-
if (client->requestBodyLength >= 0) {
|
2577
|
-
size = std::min<unsigned long long>(
|
2578
|
-
size,
|
2579
|
-
(unsigned long long) client->requestBodyLength - client->requestBodyAlreadyRead
|
2580
|
-
);
|
2581
|
-
}
|
2582
|
-
|
2583
|
-
RH_TRACE(client, 3, "Forwarding " << size << " bytes of client body data to application.");
|
2584
|
-
|
2585
|
-
if (client->session == NULL) {
|
2586
|
-
RH_TRACE(client, 2, "Application had already sent EOF. Stop reading client input.");
|
2587
|
-
client->clientInput->stop();
|
2588
|
-
syscalls::shutdown(client->fd, SHUT_RD);
|
2589
|
-
return 0;
|
2590
|
-
}
|
2591
|
-
|
2592
|
-
ssize_t ret = syscalls::write(client->session->fd(), data, size);
|
2593
|
-
int e = errno;
|
2594
|
-
if (ret == -1) {
|
2595
|
-
RH_TRACE(client, 3, "Could not write to application socket: " << strerror(e) << " (errno=" << e << ")");
|
2596
|
-
if (e == EAGAIN) {
|
2597
|
-
RH_TRACE(client, 3, "Waiting until the application socket is writable again.");
|
2598
|
-
client->clientInput->stop();
|
2599
|
-
client->appOutputWatcher.start();
|
2600
|
-
} else if (e == EPIPE || e == ECONNRESET) {
|
2601
|
-
// Client will be disconnected after response forwarding is done.
|
2602
|
-
client->clientInput->stop();
|
2603
|
-
syscalls::shutdown(client->fd, SHUT_RD);
|
2604
|
-
} else {
|
2605
|
-
disconnectWithAppSocketWriteError(client, e);
|
2606
|
-
}
|
2607
|
-
return 0;
|
2608
|
-
} else {
|
2609
|
-
client->requestBodyAlreadyRead += ret;
|
2610
|
-
|
2611
|
-
RH_TRACE(client, 3, "Managed to forward " << ret << " bytes; total=" <<
|
2612
|
-
client->requestBodyAlreadyRead << ", content-length=" << client->requestBodyLength);
|
2613
|
-
assert(client->requestBodyLength == -1 || client->requestBodyAlreadyRead <= (unsigned long long) client->requestBodyLength);
|
2614
|
-
if (client->requestBodyLength >= 0 && client->requestBodyAlreadyRead == (unsigned long long) client->requestBodyLength) {
|
2615
|
-
client->clientInput->stop();
|
2616
|
-
state_forwardingBodyToApp_onClientEof(client);
|
2617
|
-
}
|
2618
|
-
|
2619
|
-
return ret;
|
2620
|
-
}
|
2621
|
-
}
|
2622
|
-
|
2623
|
-
void state_forwardingBodyToApp_onClientEof(const ClientPtr &client) {
|
2624
|
-
state_forwardingBodyToApp_verifyInvariants(client);
|
2625
|
-
assert(!client->requestBodyIsBuffered);
|
2626
|
-
|
2627
|
-
RH_TRACE(client, 2, "End of (unbuffered) client body reached; done sending data to application");
|
2628
|
-
client->clientInput->stop();
|
2629
|
-
if (client->session != NULL && client->shouldHalfCloseWrite()) {
|
2630
|
-
syscalls::shutdown(client->session->fd(), SHUT_WR);
|
2631
|
-
}
|
2632
|
-
}
|
2633
|
-
|
2634
|
-
void state_forwardingBodyToApp_onAppOutputWritable(const ClientPtr &client) {
|
2635
|
-
state_forwardingBodyToApp_verifyInvariants(client);
|
2636
|
-
|
2637
|
-
RH_TRACE(client, 3, "Application socket became writable again.");
|
2638
|
-
client->appOutputWatcher.stop();
|
2639
|
-
if (client->requestBodyIsBuffered) {
|
2640
|
-
assert(!client->clientBodyBuffer->isStarted());
|
2641
|
-
client->clientBodyBuffer->start();
|
2642
|
-
} else {
|
2643
|
-
assert(!client->clientInput->isStarted());
|
2644
|
-
client->clientInput->start();
|
2645
|
-
}
|
2646
|
-
}
|
2647
|
-
|
2648
|
-
|
2649
|
-
void state_forwardingBodyToApp_onClientBodyBufferData(const ClientPtr &client,
|
2650
|
-
const char *data, size_t size, const FileBackedPipe::ConsumeCallback &consumed)
|
2651
|
-
{
|
2652
|
-
state_forwardingBodyToApp_verifyInvariants(client);
|
2653
|
-
assert(client->requestBodyIsBuffered);
|
2654
|
-
|
2655
|
-
RH_TRACE(client, 3, "Forwarding " << size << " bytes of buffered client body data to application.");
|
2656
|
-
|
2657
|
-
if (client->session == NULL) {
|
2658
|
-
RH_TRACE(client, 2, "Application had already sent EOF. Stop reading client input.");
|
2659
|
-
syscalls::shutdown(client->fd, SHUT_RD);
|
2660
|
-
consumed(0, true);
|
2661
|
-
return;
|
2662
|
-
}
|
2663
|
-
|
2664
|
-
ssize_t ret = syscalls::write(client->session->fd(), data, size);
|
2665
|
-
if (ret == -1) {
|
2666
|
-
int e = errno;
|
2667
|
-
RH_TRACE(client, 3, "Could not write to application socket: " << strerror(e) << " (errno=" << e << ")");
|
2668
|
-
if (e == EAGAIN) {
|
2669
|
-
RH_TRACE(client, 3, "Waiting until the application socket is writable again.");
|
2670
|
-
client->appOutputWatcher.start();
|
2671
|
-
consumed(0, true);
|
2672
|
-
} else if (e == EPIPE || e == ECONNRESET) {
|
2673
|
-
// Client will be disconnected after response forwarding is done.
|
2674
|
-
syscalls::shutdown(client->fd, SHUT_RD);
|
2675
|
-
consumed(0, true);
|
2676
|
-
} else {
|
2677
|
-
disconnectWithAppSocketWriteError(client, e);
|
2678
|
-
}
|
2679
|
-
} else {
|
2680
|
-
RH_TRACE(client, 3, "Managed to forward " << ret << " bytes.");
|
2681
|
-
consumed(ret, false);
|
2682
|
-
}
|
2683
|
-
}
|
2684
|
-
|
2685
|
-
void state_forwardingBodyToApp_onClientBodyBufferEnd(const ClientPtr &client) {
|
2686
|
-
state_forwardingBodyToApp_verifyInvariants(client);
|
2687
|
-
assert(client->requestBodyIsBuffered);
|
2688
|
-
|
2689
|
-
RH_TRACE(client, 2, "End of (buffered) client body reached; done sending data to application");
|
2690
|
-
if (client->session != NULL && client->shouldHalfCloseWrite()) {
|
2691
|
-
syscalls::shutdown(client->session->fd(), SHUT_WR);
|
2692
|
-
}
|
2693
|
-
}
|
2694
|
-
|
2695
|
-
|
2696
|
-
public:
|
2697
|
-
// For unit testing purposes.
|
2698
|
-
unsigned int connectPasswordTimeout; // milliseconds
|
2699
|
-
|
2700
|
-
BenchmarkPoint benchmarkPoint;
|
2701
|
-
|
2702
|
-
RequestHandler(const SafeLibevPtr &_libev,
|
2703
|
-
const FileDescriptor &_requestSocket,
|
2704
|
-
const PoolPtr &_pool,
|
2705
|
-
const AgentOptions &_options)
|
2706
|
-
: libev(_libev),
|
2707
|
-
requestSocket(_requestSocket),
|
2708
|
-
pool(_pool),
|
2709
|
-
options(_options),
|
2710
|
-
resourceLocator(_options.passengerRoot),
|
2711
|
-
upgradeHeaderRegex("(keep-alive, *)?upgrade(, *keep-alive)?",
|
2712
|
-
boost::regex::perl | boost::regex::icase),
|
2713
|
-
benchmarkPoint(getDefaultBenchmarkPoint())
|
2714
|
-
{
|
2715
|
-
accept4Available = true;
|
2716
|
-
connectPasswordTimeout = 15000;
|
2717
|
-
unionStationCore = pool->getUnionStationCore();
|
2718
|
-
|
2719
|
-
requestSocketWatcher.set(_requestSocket, ev::READ);
|
2720
|
-
requestSocketWatcher.set(_libev->getLoop());
|
2721
|
-
requestSocketWatcher.set<RequestHandler, &RequestHandler::onAcceptable>(this);
|
2722
|
-
requestSocketWatcher.start();
|
2723
|
-
|
2724
|
-
resumeSocketWatcherTimer.set<RequestHandler, &RequestHandler::onResumeSocketWatcher>(this);
|
2725
|
-
resumeSocketWatcherTimer.set(_libev->getLoop());
|
2726
|
-
resumeSocketWatcherTimer.set(3, 3);
|
2727
|
-
}
|
2728
|
-
|
2729
|
-
template<typename Stream>
|
2730
|
-
void inspect(Stream &stream) const {
|
2731
|
-
stream << clients.size() << " clients:\n";
|
2732
|
-
HashMap<int, ClientPtr>::const_iterator it;
|
2733
|
-
for (it = clients.begin(); it != clients.end(); it++) {
|
2734
|
-
const ClientPtr &client = it->second;
|
2735
|
-
stream << " Client " << client->fd << ":\n";
|
2736
|
-
client->inspect(stream);
|
2737
|
-
}
|
2738
|
-
}
|
2739
|
-
|
2740
|
-
void resetInactivityTime() {
|
2741
|
-
libev->run(boost::bind(&RequestHandler::doResetInactivityTime, this));
|
2742
|
-
}
|
2743
|
-
|
2744
|
-
unsigned long long inactivityTime() const {
|
2745
|
-
unsigned long long result;
|
2746
|
-
libev->run(boost::bind(&RequestHandler::getInactivityTime, this, &result));
|
2747
|
-
return result;
|
514
|
+
return doc;
|
2748
515
|
}
|
2749
516
|
};
|
2750
517
|
|