passenger 5.0.0.beta3 → 5.0.0.rc1

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.

Files changed (218) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/.editorconfig +11 -5
  5. data/CHANGELOG +38 -0
  6. data/CONTRIBUTING.md +1 -4
  7. data/Gemfile +0 -1
  8. data/Gemfile.lock +0 -2
  9. data/Rakefile +33 -33
  10. data/bin/passenger +1 -1
  11. data/bin/passenger-config +1 -1
  12. data/bin/passenger-install-apache2-module +800 -800
  13. data/bin/passenger-install-nginx-module +592 -592
  14. data/bin/passenger-memory-stats +127 -127
  15. data/bin/passenger-status +216 -216
  16. data/build/agents.rb +127 -127
  17. data/build/apache2.rb +87 -87
  18. data/build/basics.rb +60 -60
  19. data/build/common_library.rb +165 -165
  20. data/build/cplusplus_support.rb +51 -51
  21. data/build/cxx_tests.rb +268 -268
  22. data/build/debian.rb +143 -143
  23. data/build/documentation.rb +58 -58
  24. data/build/integration_tests.rb +81 -81
  25. data/build/misc.rb +132 -132
  26. data/build/nginx.rb +20 -20
  27. data/build/node_tests.rb +7 -7
  28. data/build/oxt_tests.rb +14 -14
  29. data/build/packaging.rb +570 -570
  30. data/build/preprocessor.rb +260 -260
  31. data/build/rake_extensions.rb +71 -71
  32. data/build/ruby_extension.rb +29 -29
  33. data/build/ruby_tests.rb +6 -6
  34. data/build/test_basics.rb +37 -37
  35. data/debian.template/control.template +3 -5
  36. data/dev/copy_boost_headers +134 -134
  37. data/dev/install_scripts_bootstrap_code.rb +25 -25
  38. data/dev/list_tests +20 -20
  39. data/dev/ruby_server.rb +223 -223
  40. data/dev/runner +18 -18
  41. data/doc/ServerOptimizationGuide.txt.md +55 -2
  42. data/doc/Users guide Nginx.txt +0 -26
  43. data/doc/Users guide Standalone.txt +5 -1
  44. data/doc/users_guide_snippets/tips.txt +9 -0
  45. data/ext/common/ApplicationPool2/Group.h +23 -11
  46. data/ext/common/ApplicationPool2/Implementation.cpp +32 -7
  47. data/ext/common/ApplicationPool2/Pool.h +22 -17
  48. data/ext/common/ApplicationPool2/SmartSpawner.h +4 -1
  49. data/ext/common/ApplicationPool2/Spawner.h +1 -1
  50. data/ext/common/Constants.h +1 -1
  51. data/ext/common/agents/Base.cpp +35 -20
  52. data/ext/common/agents/HelperAgent/Main.cpp +8 -1
  53. data/ext/common/agents/HelperAgent/OptionParser.h +18 -4
  54. data/ext/common/agents/HelperAgent/RequestHandler.h +2 -83
  55. data/ext/common/agents/HelperAgent/RequestHandler/ForwardResponse.cpp +54 -1
  56. data/ext/common/agents/HelperAgent/RequestHandler/InitRequest.cpp +7 -4
  57. data/ext/common/agents/Main.cpp +1 -1
  58. data/ext/common/agents/Watchdog/Main.cpp +54 -19
  59. data/ext/nginx/Configuration.c +7 -0
  60. data/ext/nginx/ContentHandler.c +9 -1
  61. data/helper-scripts/backtrace-sanitizer.rb +106 -87
  62. data/helper-scripts/crash-watch.rb +32 -0
  63. data/helper-scripts/download_binaries/extconf.rb +38 -38
  64. data/helper-scripts/meteor-loader.rb +107 -107
  65. data/helper-scripts/prespawn +101 -101
  66. data/helper-scripts/rack-loader.rb +96 -96
  67. data/helper-scripts/rack-preloader.rb +137 -137
  68. data/lib/phusion_passenger.rb +292 -292
  69. data/lib/phusion_passenger/abstract_installer.rb +438 -438
  70. data/lib/phusion_passenger/active_support3_extensions/init.rb +168 -170
  71. data/lib/phusion_passenger/admin_tools.rb +20 -20
  72. data/lib/phusion_passenger/admin_tools/instance.rb +178 -178
  73. data/lib/phusion_passenger/admin_tools/instance_registry.rb +61 -61
  74. data/lib/phusion_passenger/admin_tools/memory_stats.rb +267 -267
  75. data/lib/phusion_passenger/apache2/config_options.rb +182 -182
  76. data/lib/phusion_passenger/common_library.rb +479 -485
  77. data/lib/phusion_passenger/config/about_command.rb +161 -161
  78. data/lib/phusion_passenger/config/admin_command_command.rb +129 -129
  79. data/lib/phusion_passenger/config/agent_compiler.rb +121 -121
  80. data/lib/phusion_passenger/config/build_native_support_command.rb +43 -43
  81. data/lib/phusion_passenger/config/command.rb +25 -25
  82. data/lib/phusion_passenger/config/compile_agent_command.rb +62 -62
  83. data/lib/phusion_passenger/config/compile_nginx_engine_command.rb +88 -73
  84. data/lib/phusion_passenger/config/detach_process_command.rb +72 -72
  85. data/lib/phusion_passenger/config/download_agent_command.rb +246 -227
  86. data/lib/phusion_passenger/config/download_nginx_engine_command.rb +245 -224
  87. data/lib/phusion_passenger/config/install_agent_command.rb +144 -132
  88. data/lib/phusion_passenger/config/install_standalone_runtime_command.rb +205 -185
  89. data/lib/phusion_passenger/config/installation_utils.rb +204 -204
  90. data/lib/phusion_passenger/config/list_instances_command.rb +64 -64
  91. data/lib/phusion_passenger/config/main.rb +152 -152
  92. data/lib/phusion_passenger/config/nginx_engine_compiler.rb +319 -300
  93. data/lib/phusion_passenger/config/reopen_logs_command.rb +67 -67
  94. data/lib/phusion_passenger/config/restart_app_command.rb +155 -155
  95. data/lib/phusion_passenger/config/system_metrics_command.rb +13 -13
  96. data/lib/phusion_passenger/config/utils.rb +95 -95
  97. data/lib/phusion_passenger/config/validate_install_command.rb +198 -198
  98. data/lib/phusion_passenger/console_text_template.rb +25 -25
  99. data/lib/phusion_passenger/constants.rb +90 -90
  100. data/lib/phusion_passenger/debug_logging.rb +106 -106
  101. data/lib/phusion_passenger/loader_shared_helpers.rb +447 -432
  102. data/lib/phusion_passenger/message_channel.rb +312 -312
  103. data/lib/phusion_passenger/message_client.rb +176 -176
  104. data/lib/phusion_passenger/native_support.rb +369 -369
  105. data/lib/phusion_passenger/nginx/config_options.rb +297 -297
  106. data/lib/phusion_passenger/packaging.rb +131 -131
  107. data/lib/phusion_passenger/platform_info.rb +360 -360
  108. data/lib/phusion_passenger/platform_info/apache.rb +767 -767
  109. data/lib/phusion_passenger/platform_info/apache_detector.rb +199 -199
  110. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +107 -107
  111. data/lib/phusion_passenger/platform_info/compiler.rb +570 -570
  112. data/lib/phusion_passenger/platform_info/curl.rb +32 -32
  113. data/lib/phusion_passenger/platform_info/cxx_portability.rb +188 -188
  114. data/lib/phusion_passenger/platform_info/depcheck.rb +372 -372
  115. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +109 -109
  116. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
  117. data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +10 -34
  118. data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +101 -101
  119. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +5 -5
  120. data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +13 -13
  121. data/lib/phusion_passenger/platform_info/linux.rb +55 -55
  122. data/lib/phusion_passenger/platform_info/operating_system.rb +149 -149
  123. data/lib/phusion_passenger/platform_info/ruby.rb +468 -448
  124. data/lib/phusion_passenger/platform_info/zlib.rb +9 -9
  125. data/lib/phusion_passenger/plugin.rb +66 -66
  126. data/lib/phusion_passenger/preloader_shared_helpers.rb +126 -126
  127. data/lib/phusion_passenger/public_api.rb +191 -191
  128. data/lib/phusion_passenger/rack/out_of_band_gc.rb +93 -94
  129. data/lib/phusion_passenger/rack/thread_handler_extension.rb +231 -227
  130. data/lib/phusion_passenger/request_handler.rb +567 -577
  131. data/lib/phusion_passenger/request_handler/thread_handler.rb +379 -381
  132. data/lib/phusion_passenger/ruby_core_enhancements.rb +86 -86
  133. data/lib/phusion_passenger/ruby_core_io_enhancements.rb +74 -74
  134. data/lib/phusion_passenger/simple_benchmarking.rb +25 -25
  135. data/lib/phusion_passenger/standalone/app_finder.rb +153 -150
  136. data/lib/phusion_passenger/standalone/command.rb +44 -40
  137. data/lib/phusion_passenger/standalone/config_utils.rb +53 -53
  138. data/lib/phusion_passenger/standalone/control_utils.rb +38 -59
  139. data/lib/phusion_passenger/standalone/main.rb +73 -73
  140. data/lib/phusion_passenger/standalone/start_command.rb +697 -685
  141. data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +193 -155
  142. data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +162 -133
  143. data/lib/phusion_passenger/standalone/status_command.rb +64 -64
  144. data/lib/phusion_passenger/standalone/stop_command.rb +72 -72
  145. data/lib/phusion_passenger/standalone/version_command.rb +9 -9
  146. data/lib/phusion_passenger/union_station/connection.rb +32 -32
  147. data/lib/phusion_passenger/union_station/core.rb +251 -251
  148. data/lib/phusion_passenger/union_station/transaction.rb +126 -126
  149. data/lib/phusion_passenger/utils.rb +199 -167
  150. data/lib/phusion_passenger/utils/ansi_colors.rb +128 -128
  151. data/lib/phusion_passenger/utils/download.rb +196 -196
  152. data/lib/phusion_passenger/utils/file_system_watcher.rb +158 -158
  153. data/lib/phusion_passenger/utils/hosts_file_parser.rb +101 -101
  154. data/lib/phusion_passenger/utils/lock.rb +31 -31
  155. data/lib/phusion_passenger/utils/native_support_utils.rb +31 -31
  156. data/lib/phusion_passenger/utils/progress_bar.rb +26 -26
  157. data/lib/phusion_passenger/utils/shellwords.rb +20 -20
  158. data/lib/phusion_passenger/utils/terminal_choice_menu.rb +206 -206
  159. data/lib/phusion_passenger/utils/unseekable_socket.rb +272 -272
  160. data/lib/phusion_passenger/vendor/crash_watch/app.rb +129 -0
  161. data/lib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +341 -0
  162. data/lib/phusion_passenger/vendor/crash_watch/version.rb +24 -0
  163. data/lib/phusion_passenger/vendor/daemon_controller.rb +877 -0
  164. data/lib/phusion_passenger/vendor/daemon_controller/lock_file.rb +127 -0
  165. data/lib/phusion_passenger/vendor/daemon_controller/spawn.rb +26 -0
  166. data/lib/phusion_passenger/vendor/daemon_controller/version.rb +29 -0
  167. data/packaging/rpm/passenger_spec/passenger.spec.template +0 -1
  168. data/passenger.gemspec +0 -1
  169. data/resources/templates/config/nginx_engine_compiler/possible_solutions_for_download_and_extraction_problems.txt.erb +27 -0
  170. data/resources/templates/standalone/config.erb +19 -15
  171. data/test/integration_tests/apache2_tests.rb +566 -566
  172. data/test/integration_tests/downloaded_binaries_tests.rb +126 -125
  173. data/test/integration_tests/native_packaging_spec.rb +296 -296
  174. data/test/integration_tests/nginx_tests.rb +393 -393
  175. data/test/integration_tests/shared/example_webapp_tests.rb +282 -280
  176. data/test/integration_tests/source_packaging_test.rb +138 -138
  177. data/test/integration_tests/spec_helper.rb +5 -5
  178. data/test/integration_tests/standalone_tests.rb +367 -367
  179. data/test/ruby/debug_logging_spec.rb +133 -133
  180. data/test/ruby/message_channel_spec.rb +186 -186
  181. data/test/ruby/rack/loader_spec.rb +28 -28
  182. data/test/ruby/rack/preloader_spec.rb +34 -34
  183. data/test/ruby/rails3.0/loader_spec.rb +12 -12
  184. data/test/ruby/rails3.0/preloader_spec.rb +18 -18
  185. data/test/ruby/rails3.1/loader_spec.rb +12 -12
  186. data/test/ruby/rails3.1/preloader_spec.rb +18 -18
  187. data/test/ruby/rails3.2/loader_spec.rb +12 -12
  188. data/test/ruby/rails3.2/preloader_spec.rb +18 -18
  189. data/test/ruby/rails4.0/loader_spec.rb +12 -12
  190. data/test/ruby/rails4.0/preloader_spec.rb +18 -18
  191. data/test/ruby/rails4.1/loader_spec.rb +12 -12
  192. data/test/ruby/rails4.1/preloader_spec.rb +18 -18
  193. data/test/ruby/request_handler_spec.rb +730 -730
  194. data/test/ruby/shared/loader_sharedspec.rb +224 -224
  195. data/test/ruby/shared/rails/union_station_extensions_sharedspec.rb +327 -327
  196. data/test/ruby/shared/ruby_loader_sharedspec.rb +47 -47
  197. data/test/ruby/spec_helper.rb +65 -65
  198. data/test/ruby/standalone/runtime_installer_spec.rb +384 -384
  199. data/test/ruby/union_station_spec.rb +276 -276
  200. data/test/ruby/utils/file_system_watcher_spec.rb +220 -220
  201. data/test/ruby/utils/hosts_file_parser.rb +248 -248
  202. data/test/ruby/utils/tee_input_spec.rb +215 -215
  203. data/test/ruby/utils/unseekable_socket_spec.rb +57 -57
  204. data/test/ruby/utils_spec.rb +21 -21
  205. data/test/stub/rack/config.ru +87 -87
  206. data/test/stub/rack/library.rb +8 -8
  207. data/test/stub/rack/start.rb +30 -30
  208. data/test/support/apache2_controller.rb +191 -191
  209. data/test/support/nginx_controller.rb +90 -99
  210. data/test/support/placebo-preloader.rb +57 -57
  211. data/test/support/test_helper.rb +435 -435
  212. metadata +11 -21
  213. metadata.gz.asc +7 -7
  214. data/lib/phusion_passenger/standalone/command2.rb +0 -292
  215. data/lib/phusion_passenger/standalone/start2_command.rb +0 -799
  216. data/resources/templates/standalone/download_tool_missing.txt.erb +0 -18
  217. data/resources/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -17
  218. data/resources/templates/standalone/run_installer_as_root.txt.erb +0 -8
@@ -5,7 +5,7 @@
5
5
  # as well as the Nginx module config script, so that they work no
6
6
  # matter which Ruby interpreter is currently in $PATH, and no matter how
7
7
  # Phusion Passenger is packaged.
8
- #
8
+ #
9
9
  # The bootstrap code must not add ruby_libdir to $LOAD_PATH. The active Ruby
10
10
  # can be *any* Ruby interpreter, maybe not even MRI. ruby_libdir belongs to
11
11
  # a Ruby interpreter installed by the distribution, and the files in it may
@@ -14,33 +14,33 @@
14
14
  type = ARGV.shift
15
15
 
16
16
  if type == "--ruby"
17
- ruby_libdir = ARGV.shift
18
- BOOTSTRAP_CODE = %Q{
19
- ENV["PASSENGER_LOCATION_CONFIGURATION_FILE"] = "#{ruby_libdir}/phusion_passenger/locations.ini"
20
- begin
21
- require 'rubygems'
22
- rescue LoadError
23
- end
24
- require '#{ruby_libdir}/phusion_passenger'
25
- }
17
+ ruby_libdir = ARGV.shift
18
+ BOOTSTRAP_CODE = %Q{
19
+ ENV["PASSENGER_LOCATION_CONFIGURATION_FILE"] = "#{ruby_libdir}/phusion_passenger/locations.ini"
20
+ begin
21
+ require 'rubygems'
22
+ rescue LoadError
23
+ end
24
+ require '#{ruby_libdir}/phusion_passenger'
25
+ }
26
26
  elsif type == "--nginx-module-config"
27
- bindir = ARGV.shift
28
- BOOTSTRAP_CODE = %Q{
29
- PASSENGER_CONFIG=#{bindir}/passenger-config
30
- }
27
+ bindir = ARGV.shift
28
+ BOOTSTRAP_CODE = %Q{
29
+ PASSENGER_CONFIG=#{bindir}/passenger-config
30
+ }
31
31
  else
32
- abort "Invalid type"
32
+ abort "Invalid type"
33
33
  end
34
- BOOTSTRAP_CODE.gsub!(/^\t\t/, '').strip
34
+ BOOTSTRAP_CODE.gsub!(/^ ( )?/, '').strip
35
35
 
36
36
  ARGV.each do |filename|
37
- File.open(filename, "r+") do |f|
38
- text = f.read
39
- text.sub!(
40
- /^## Magic comment: begin bootstrap ##.*## Magic comment: end bootstrap \#\#$/m,
41
- BOOTSTRAP_CODE)
42
- f.rewind
43
- f.truncate(0)
44
- f.write(text)
45
- end
37
+ File.open(filename, "r+") do |f|
38
+ text = f.read
39
+ text.sub!(
40
+ /^## Magic comment: begin bootstrap ##.*## Magic comment: end bootstrap \#\#$/m,
41
+ BOOTSTRAP_CODE)
42
+ f.rewind
43
+ f.truncate(0)
44
+ f.write(text)
45
+ end
46
46
  end
data/dev/list_tests CHANGED
@@ -9,32 +9,32 @@ require_relative '../lib/phusion_passenger/utils/ansi_colors'
9
9
  include PhusionPassenger::Utils::AnsiColors
10
10
 
11
11
  def extract_category_name(occurrence)
12
- occurrence =~ / (.+) /
13
- return $1
12
+ occurrence =~ / (.+) /
13
+ return $1
14
14
  end
15
15
 
16
16
  def extract_test_name(occurrence)
17
- occurrence = occurrence.sub(/.*?\((.+)\).*/m, '\1')
18
- occurrence.gsub!(/"\n[ \t]*"/m, '')
19
- occurrence.sub!(/\A"/, '')
20
- occurrence.sub!(/"\Z/, '')
21
- return occurrence
17
+ occurrence = occurrence.sub(/.*?\((.+)\).*/m, '\1')
18
+ occurrence.gsub!(/"\n[ \t]*"/m, '')
19
+ occurrence.sub!(/\A"/, '')
20
+ occurrence.sub!(/"\Z/, '')
21
+ return occurrence
22
22
  end
23
23
 
24
24
  def start(filename)
25
- STDOUT.write(DEFAULT_TERMINAL_COLOR)
26
- begin
27
- occurrences = File.read(filename).scan(%r{/\*\*\*\*\* .+? \*\*\*\*\*/|set_test_name\(.+?\);}m)
28
- occurrences.each do |occurrence|
29
- if occurrence =~ %r{\A/}
30
- puts ansi_colorize("<b>" + extract_category_name(occurrence) + "</b>")
31
- else
32
- puts " " + extract_test_name(occurrence)
33
- end
34
- end
35
- ensure
36
- STDOUT.write(RESET)
37
- end
25
+ STDOUT.write(DEFAULT_TERMINAL_COLOR)
26
+ begin
27
+ occurrences = File.read(filename).scan(%r{/\*\*\*\*\* .+? \*\*\*\*\*/|set_test_name\(.+?\);}m)
28
+ occurrences.each do |occurrence|
29
+ if occurrence =~ %r{\A/}
30
+ puts ansi_colorize("<b>" + extract_category_name(occurrence) + "</b>")
31
+ else
32
+ puts " " + extract_test_name(occurrence)
33
+ end
34
+ end
35
+ ensure
36
+ STDOUT.write(RESET)
37
+ end
38
38
  end
39
39
 
40
40
  start(ARGV[0])
data/dev/ruby_server.rb CHANGED
@@ -8,237 +8,237 @@ require 'socket'
8
8
  require 'optparse'
9
9
 
10
10
  class TestServer
11
- REQUEST =
12
- "GET / HTTP/1.1\r\n" <<
13
- "Connection: Keep-Alive\r\n" <<
14
- "Host: 127.0.0.1:3001\r\n" <<
15
- "User-Agent: ApacheBench/2.3\r\n" <<
16
- "Accept: */*\r\n\r\n"
17
-
18
- RESPONSE =
19
- "HTTP/1.1 200 OK\r\n" <<
20
- "Status: 200 OK\r\n" <<
21
- "Content-Type: text/plain\r\n" <<
22
- "Content-Length: 3\r\n" <<
23
- "Connection: keep-alive\r\n" <<
24
- "\r\n" <<
25
- "ok\n"
26
-
27
- def initialize(options = {})
28
- @options = options
29
- @options[:transport] ||= :tcp
30
- @options[:protocol] ||= :http
31
- @options[:port] ||= 3000
32
- @options[:file] ||= './socket'
33
- @options[:threads] ||= 2
34
- @options[:processes] ||= 2
35
- @forward = @options[:forward]
36
- @forward_transport = @options[:forward_transport]
37
- @forward_file = @options[:forward_file]
38
- @forward_port = @options[:forward_port]
39
- @forward_keep_alive = @options[:forward_keep_alive]
40
- end
41
-
42
- def run
43
- case @options[:transport]
44
- when :tcp
45
- @server = TCPServer.new('127.0.0.1', @options[:port])
46
- @server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
47
- puts "Listening on http://127.0.0.1:#{@options[:port]}/"
48
- when :unix
49
- File.unlink(@options[:file]) rescue nil
50
- @server = UNIXServer.new(@options[:file])
51
- puts "Listening on Unix domain socket: #{@options[:file]}"
52
- else
53
- abort "Unknown transport #{@options[:transport]}"
54
- end
55
- @server.listen(100)
56
-
57
- case @options[:protocol]
58
- when :http
59
- puts "Using HTTP protocol"
60
- @protocol = :http
61
- when :session
62
- puts "Using session protocol"
63
- @protocol = :session
64
- else
65
- abort "Unknown protocol #{@options[:protocol]}"
66
- end
67
-
68
- if @forward
69
- case @forward_transport
70
- when :tcp
71
- puts "Forwarding to http://127.0.0.1:#{@forward_port}/"
72
- when :unix
73
- puts "Forwarding to Unix domain socket: #{@forward_file}"
74
- end
75
- end
76
-
77
- puts "Using #{@options[:processes]} processes"
78
- puts "Using #{@options[:threads]} threads per process"
79
- fork_children
80
- threads = []
81
- @options[:threads].times { threads << start_thread }
82
- begin
83
- threads.each { |t| t.join }
84
- rescue Interrupt
85
- end
86
- end
11
+ REQUEST =
12
+ "GET / HTTP/1.1\r\n" <<
13
+ "Connection: Keep-Alive\r\n" <<
14
+ "Host: 127.0.0.1:3001\r\n" <<
15
+ "User-Agent: ApacheBench/2.3\r\n" <<
16
+ "Accept: */*\r\n\r\n"
17
+
18
+ RESPONSE =
19
+ "HTTP/1.1 200 OK\r\n" <<
20
+ "Status: 200 OK\r\n" <<
21
+ "Content-Type: text/plain\r\n" <<
22
+ "Content-Length: 3\r\n" <<
23
+ "Connection: keep-alive\r\n" <<
24
+ "\r\n" <<
25
+ "ok\n"
26
+
27
+ def initialize(options = {})
28
+ @options = options
29
+ @options[:transport] ||= :tcp
30
+ @options[:protocol] ||= :http
31
+ @options[:port] ||= 3000
32
+ @options[:file] ||= './socket'
33
+ @options[:threads] ||= 2
34
+ @options[:processes] ||= 2
35
+ @forward = @options[:forward]
36
+ @forward_transport = @options[:forward_transport]
37
+ @forward_file = @options[:forward_file]
38
+ @forward_port = @options[:forward_port]
39
+ @forward_keep_alive = @options[:forward_keep_alive]
40
+ end
41
+
42
+ def run
43
+ case @options[:transport]
44
+ when :tcp
45
+ @server = TCPServer.new('127.0.0.1', @options[:port])
46
+ @server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
47
+ puts "Listening on http://127.0.0.1:#{@options[:port]}/"
48
+ when :unix
49
+ File.unlink(@options[:file]) rescue nil
50
+ @server = UNIXServer.new(@options[:file])
51
+ puts "Listening on Unix domain socket: #{@options[:file]}"
52
+ else
53
+ abort "Unknown transport #{@options[:transport]}"
54
+ end
55
+ @server.listen(100)
56
+
57
+ case @options[:protocol]
58
+ when :http
59
+ puts "Using HTTP protocol"
60
+ @protocol = :http
61
+ when :session
62
+ puts "Using session protocol"
63
+ @protocol = :session
64
+ else
65
+ abort "Unknown protocol #{@options[:protocol]}"
66
+ end
67
+
68
+ if @forward
69
+ case @forward_transport
70
+ when :tcp
71
+ puts "Forwarding to http://127.0.0.1:#{@forward_port}/"
72
+ when :unix
73
+ puts "Forwarding to Unix domain socket: #{@forward_file}"
74
+ end
75
+ end
76
+
77
+ puts "Using #{@options[:processes]} processes"
78
+ puts "Using #{@options[:threads]} threads per process"
79
+ fork_children
80
+ threads = []
81
+ @options[:threads].times { threads << start_thread }
82
+ begin
83
+ threads.each { |t| t.join }
84
+ rescue Interrupt
85
+ end
86
+ end
87
87
 
88
88
  private
89
- def fork_children
90
- if @options[:processes] == 1
91
- return
92
- end
93
-
94
- children = []
95
- @options[:processes].times do
96
- pid = fork
97
- if pid
98
- # Parent
99
- puts "Spawned child process: #{pid}"
100
- children << pid
101
- else
102
- return
103
- end
104
- end
105
- if !children.empty?
106
- # Parent
107
- begin
108
- sleep 999999
109
- rescue Interrupt
110
- exit
111
- ensure
112
- children.each do |pid|
113
- puts "Reaping child process: #{pid}"
114
- Process.kill('INT', pid)
115
- end
116
- children.each do |pid|
117
- Process.waitpid(pid)
118
- end
119
- end
120
- end
121
- end
122
-
123
- def start_thread
124
- Thread.new do
125
- Thread.current.abort_on_exception = true
126
- if @forward && @forward_keep_alive
127
- forward_connection = connect_to_forwarding_target
128
- end
129
- while true
130
- handle_next_client(forward_connection)
131
- end
132
- end
133
- end
134
-
135
- def handle_next_client(forward_connection)
136
- client = @server.accept
137
- begin
138
- buffer = "".force_encoding("binary")
139
- while true
140
- begin
141
- read_header(client, buffer)
142
-
143
- if @forward
144
- forward(forward_connection)
145
- end
146
-
147
- # Write response
148
- client.write(RESPONSE)
149
- rescue EOFError, Errno::ECONNRESET
150
- break
151
- end
152
- end
153
- ensure
154
- client.close
155
- end
156
- end
157
-
158
- def read_header(client, buffer)
159
- if @protocol == :http
160
- while client.readline != "\r\n"
161
- # Do nothing.
162
- end
163
- else
164
- temp = client.read(4, buffer)
165
- raise EOFError if temp.nil?
166
- size = temp.unpack('N')[0]
167
- temp = client.read(size, buffer)
168
- raise EOFError if temp.nil?
169
- end
170
- end
171
-
172
- def forward(target_connection)
173
- if target_connection
174
- io = target_connection
175
- else
176
- io = connect_to_forwarding_target
177
- end
178
- begin
179
- io.write(REQUEST)
180
- while io.readline != "ok\n"
181
- # Do nothing
182
- end
183
- ensure
184
- if !target_connection
185
- io.close
186
- end
187
- end
188
- end
189
-
190
- def connect_to_forwarding_target
191
- if @forward_transport == :unix
192
- UNIXSocket.new(@forward_file)
193
- else
194
- TCPSocket.new('127.0.0.1', @forward_port)
195
- end
196
- end
89
+ def fork_children
90
+ if @options[:processes] == 1
91
+ return
92
+ end
93
+
94
+ children = []
95
+ @options[:processes].times do
96
+ pid = fork
97
+ if pid
98
+ # Parent
99
+ puts "Spawned child process: #{pid}"
100
+ children << pid
101
+ else
102
+ return
103
+ end
104
+ end
105
+ if !children.empty?
106
+ # Parent
107
+ begin
108
+ sleep 999999
109
+ rescue Interrupt
110
+ exit
111
+ ensure
112
+ children.each do |pid|
113
+ puts "Reaping child process: #{pid}"
114
+ Process.kill('INT', pid)
115
+ end
116
+ children.each do |pid|
117
+ Process.waitpid(pid)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ def start_thread
124
+ Thread.new do
125
+ Thread.current.abort_on_exception = true
126
+ if @forward && @forward_keep_alive
127
+ forward_connection = connect_to_forwarding_target
128
+ end
129
+ while true
130
+ handle_next_client(forward_connection)
131
+ end
132
+ end
133
+ end
134
+
135
+ def handle_next_client(forward_connection)
136
+ client = @server.accept
137
+ begin
138
+ buffer = "".force_encoding("binary")
139
+ while true
140
+ begin
141
+ read_header(client, buffer)
142
+
143
+ if @forward
144
+ forward(forward_connection)
145
+ end
146
+
147
+ # Write response
148
+ client.write(RESPONSE)
149
+ rescue EOFError, Errno::ECONNRESET
150
+ break
151
+ end
152
+ end
153
+ ensure
154
+ client.close
155
+ end
156
+ end
157
+
158
+ def read_header(client, buffer)
159
+ if @protocol == :http
160
+ while client.readline != "\r\n"
161
+ # Do nothing.
162
+ end
163
+ else
164
+ temp = client.read(4, buffer)
165
+ raise EOFError if temp.nil?
166
+ size = temp.unpack('N')[0]
167
+ temp = client.read(size, buffer)
168
+ raise EOFError if temp.nil?
169
+ end
170
+ end
171
+
172
+ def forward(target_connection)
173
+ if target_connection
174
+ io = target_connection
175
+ else
176
+ io = connect_to_forwarding_target
177
+ end
178
+ begin
179
+ io.write(REQUEST)
180
+ while io.readline != "ok\n"
181
+ # Do nothing
182
+ end
183
+ ensure
184
+ if !target_connection
185
+ io.close
186
+ end
187
+ end
188
+ end
189
+
190
+ def connect_to_forwarding_target
191
+ if @forward_transport == :unix
192
+ UNIXSocket.new(@forward_file)
193
+ else
194
+ TCPSocket.new('127.0.0.1', @forward_port)
195
+ end
196
+ end
197
197
  end
198
198
 
199
199
  options = {}
200
200
  parser = OptionParser.new do |opts|
201
- opts.banner = "Usage: ./ruby.rb [options]"
202
- opts.separator ""
203
-
204
- opts.separator "Options:"
205
- opts.on("--port PORT", Integer, "Listen on the given TCP port. Default: 3000") do |val|
206
- options[:transport] = :tcp
207
- options[:port] = val
208
- end
209
- opts.on("--file PATH", String, "Listen on the given Unix domain socket file") do |val|
210
- options[:transport] = :unix
211
- options[:file] = val
212
- end
213
- opts.on("--session-protocol", "Accept session protocol instead of HTTP") do
214
- options[:protocol] = :session
215
- end
216
- opts.on("--threads N", Integer, "Number of threads to use. Default: 2") do |val|
217
- options[:threads] = val
218
- end
219
- opts.on("--processes N", Integer, "Number of processes to use. Default: 2") do |val|
220
- options[:processes] = val
221
- end
222
- opts.on("--forward-tcp PORT", Integer, "Forward request to another TCP server") do |val|
223
- options[:forward] = true
224
- options[:forward_transport] = :tcp
225
- options[:forward_port] = val
226
- end
227
- opts.on("--forward-file PATH", String, "Forward request to another Unix domain socket server") do |val|
228
- options[:forward] = true
229
- options[:forward_transport] = :unix
230
- options[:forward_file] = val
231
- end
232
- opts.on("--forward-keep-alive", "Use keep-alive when forwarding") do
233
- options[:forward_keep_alive] = true
234
- end
201
+ opts.banner = "Usage: ./ruby.rb [options]"
202
+ opts.separator ""
203
+
204
+ opts.separator "Options:"
205
+ opts.on("--port PORT", Integer, "Listen on the given TCP port. Default: 3000") do |val|
206
+ options[:transport] = :tcp
207
+ options[:port] = val
208
+ end
209
+ opts.on("--file PATH", String, "Listen on the given Unix domain socket file") do |val|
210
+ options[:transport] = :unix
211
+ options[:file] = val
212
+ end
213
+ opts.on("--session-protocol", "Accept session protocol instead of HTTP") do
214
+ options[:protocol] = :session
215
+ end
216
+ opts.on("--threads N", Integer, "Number of threads to use. Default: 2") do |val|
217
+ options[:threads] = val
218
+ end
219
+ opts.on("--processes N", Integer, "Number of processes to use. Default: 2") do |val|
220
+ options[:processes] = val
221
+ end
222
+ opts.on("--forward-tcp PORT", Integer, "Forward request to another TCP server") do |val|
223
+ options[:forward] = true
224
+ options[:forward_transport] = :tcp
225
+ options[:forward_port] = val
226
+ end
227
+ opts.on("--forward-file PATH", String, "Forward request to another Unix domain socket server") do |val|
228
+ options[:forward] = true
229
+ options[:forward_transport] = :unix
230
+ options[:forward_file] = val
231
+ end
232
+ opts.on("--forward-keep-alive", "Use keep-alive when forwarding") do
233
+ options[:forward_keep_alive] = true
234
+ end
235
235
  end
236
236
  begin
237
- parser.parse!
237
+ parser.parse!
238
238
  rescue OptionParser::ParseError => e
239
- puts e
240
- puts
241
- puts "Please see '--help' for valid options."
242
- exit 1
239
+ puts e
240
+ puts
241
+ puts "Please see '--help' for valid options."
242
+ exit 1
243
243
  end
244
244
  TestServer.new(options).run