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
@@ -22,132 +22,132 @@
22
22
  # THE SOFTWARE.
23
23
 
24
24
  module PhusionPassenger
25
- module Utils
26
-
27
- module AnsiColors
28
- RESET = "\e[0m".freeze
29
- BOLD = "\e[1m".freeze
30
- DGRAY = "\e[90m".freeze
31
- RED = "\e[31m".freeze
32
- ORANGE = "\e[38;5;214m".freeze
33
- GREEN = "\e[32m".freeze
34
- YELLOW = "\e[33m".freeze
35
- WHITE = "\e[37m".freeze
36
- BLACK_BG = "\e[40m".freeze
37
- BLUE_BG = "\e[44m".freeze
38
- DEFAULT_TERMINAL_COLOR = "#{RESET}#{WHITE}#{BLACK_BG}".freeze
39
-
40
- extend self # Make methods available as class methods.
41
-
42
- def self.new(type = :auto)
43
- return AnsiColorsPrinter.new(type)
44
- end
45
-
46
- def self.included(klass)
47
- # When included into another class, make sure that Utils
48
- # methods are made private.
49
- public_instance_methods(false).each do |method_name|
50
- klass.send(:private, method_name)
51
- end
52
- end
53
-
54
- def ansi_colorize(text)
55
- text = text.gsub(%r{<b>(.*?)</b>}m, "#{BOLD}\\1#{DEFAULT_TERMINAL_COLOR}")
56
- text.gsub!(%r{<dgray>(.*?)</dgray>}m, "#{BOLD}#{DGRAY}\\1#{DEFAULT_TERMINAL_COLOR}")
57
- text.gsub!(%r{<red>(.*?)</red>}m, "#{BOLD}#{RED}\\1#{DEFAULT_TERMINAL_COLOR}")
58
- text.gsub!(%r{<orange>(.*?)</orange>}m, "#{BOLD}#{ORANGE}\\1#{DEFAULT_TERMINAL_COLOR}")
59
- text.gsub!(%r{<green>(.*?)</green>}m, "#{BOLD}#{GREEN}\\1#{DEFAULT_TERMINAL_COLOR}")
60
- text.gsub!(%r{<yellow>(.*?)</yellow>}m, "#{BOLD}#{YELLOW}\\1#{DEFAULT_TERMINAL_COLOR}")
61
- text.gsub!(%r{<banner>(.*?)</banner>}m, "#{BOLD}#{BLUE_BG}#{YELLOW}\\1#{DEFAULT_TERMINAL_COLOR}")
62
- return text
63
- end
64
-
65
- def strip_color_tags(text)
66
- text = text.gsub(%r{<b>(.*?)</b>}m, "\\1")
67
- text = text.gsub(%r{<dgray>(.*?)</dgray>}m, "\\1")
68
- text.gsub!(%r{<red>(.*?)</red>}m, "\\1")
69
- text.gsub!(%r{<orange>(.*?)</orange>}m, "\\1")
70
- text.gsub!(%r{<green>(.*?)</green>}m, "\\1")
71
- text.gsub!(%r{<yellow>(.*?)</yellow>}m, "\\1")
72
- text.gsub!(%r{<banner>(.*?)</banner>}m, "\\1")
73
- return text
74
- end
75
- end
76
-
77
- class AnsiColorsPrinter
78
- def initialize(enabled = :auto)
79
- @enabled = enabled
80
- end
81
-
82
- def reset
83
- return maybe_colorize(AnsiColors::RESET)
84
- end
85
-
86
- def bold
87
- return maybe_colorize(AnsiColors::BOLD)
88
- end
89
-
90
- def dgray
91
- return maybe_colorize(AnsiColors::DGRAY)
92
- end
93
-
94
- def red
95
- return maybe_colorize(AnsiColors::RED)
96
- end
97
-
98
- def orange
99
- return maybe_colorize(AnsiColors::ORANGE)
100
- end
101
-
102
- def green
103
- return maybe_colorize(AnsiColors::GREEN)
104
- end
105
-
106
- def yellow
107
- return maybe_colorize(AnsiColors::YELLOW)
108
- end
109
-
110
- def white
111
- return maybe_colorize(AnsiColors::WHITE)
112
- end
113
-
114
- def black_bg
115
- return maybe_colorize(AnsiColors::BLACK_BG)
116
- end
117
-
118
- def blue_bg
119
- return maybe_colorize(AnsiColors::BLUE_BG)
120
- end
121
-
122
- def default_terminal_color
123
- return maybe_colorize(AnsiColors::DEFAULT_TERMINAL_COLOR)
124
- end
125
-
126
- def ansi_colorize(text)
127
- if should_output_color?
128
- return AnsiColors.ansi_colorize(text)
129
- else
130
- return AnsiColors.strip_color_tags(text)
131
- end
132
- end
133
-
134
- private
135
- def maybe_colorize(ansi_color)
136
- if should_output_color?
137
- return ansi_color
138
- else
139
- return ""
140
- end
141
- end
142
-
143
- def should_output_color?
144
- if @enabled == :auto
145
- return STDOUT.tty?
146
- else
147
- return @enabled
148
- end
149
- end
150
- end
151
-
152
- end # module Utils
25
+ module Utils
26
+
27
+ module AnsiColors
28
+ RESET = "\e[0m".freeze
29
+ BOLD = "\e[1m".freeze
30
+ DGRAY = "\e[90m".freeze
31
+ RED = "\e[31m".freeze
32
+ ORANGE = "\e[38;5;214m".freeze
33
+ GREEN = "\e[32m".freeze
34
+ YELLOW = "\e[33m".freeze
35
+ WHITE = "\e[37m".freeze
36
+ BLACK_BG = "\e[40m".freeze
37
+ BLUE_BG = "\e[44m".freeze
38
+ DEFAULT_TERMINAL_COLOR = "#{RESET}#{WHITE}#{BLACK_BG}".freeze
39
+
40
+ extend self # Make methods available as class methods.
41
+
42
+ def self.new(type = :auto)
43
+ return AnsiColorsPrinter.new(type)
44
+ end
45
+
46
+ def self.included(klass)
47
+ # When included into another class, make sure that Utils
48
+ # methods are made private.
49
+ public_instance_methods(false).each do |method_name|
50
+ klass.send(:private, method_name)
51
+ end
52
+ end
53
+
54
+ def ansi_colorize(text)
55
+ text = text.gsub(%r{<b>(.*?)</b>}m, "#{BOLD}\\1#{DEFAULT_TERMINAL_COLOR}")
56
+ text.gsub!(%r{<dgray>(.*?)</dgray>}m, "#{BOLD}#{DGRAY}\\1#{DEFAULT_TERMINAL_COLOR}")
57
+ text.gsub!(%r{<red>(.*?)</red>}m, "#{BOLD}#{RED}\\1#{DEFAULT_TERMINAL_COLOR}")
58
+ text.gsub!(%r{<orange>(.*?)</orange>}m, "#{BOLD}#{ORANGE}\\1#{DEFAULT_TERMINAL_COLOR}")
59
+ text.gsub!(%r{<green>(.*?)</green>}m, "#{BOLD}#{GREEN}\\1#{DEFAULT_TERMINAL_COLOR}")
60
+ text.gsub!(%r{<yellow>(.*?)</yellow>}m, "#{BOLD}#{YELLOW}\\1#{DEFAULT_TERMINAL_COLOR}")
61
+ text.gsub!(%r{<banner>(.*?)</banner>}m, "#{BOLD}#{BLUE_BG}#{YELLOW}\\1#{DEFAULT_TERMINAL_COLOR}")
62
+ return text
63
+ end
64
+
65
+ def strip_color_tags(text)
66
+ text = text.gsub(%r{<b>(.*?)</b>}m, "\\1")
67
+ text = text.gsub(%r{<dgray>(.*?)</dgray>}m, "\\1")
68
+ text.gsub!(%r{<red>(.*?)</red>}m, "\\1")
69
+ text.gsub!(%r{<orange>(.*?)</orange>}m, "\\1")
70
+ text.gsub!(%r{<green>(.*?)</green>}m, "\\1")
71
+ text.gsub!(%r{<yellow>(.*?)</yellow>}m, "\\1")
72
+ text.gsub!(%r{<banner>(.*?)</banner>}m, "\\1")
73
+ return text
74
+ end
75
+ end
76
+
77
+ class AnsiColorsPrinter
78
+ def initialize(enabled = :auto)
79
+ @enabled = enabled
80
+ end
81
+
82
+ def reset
83
+ return maybe_colorize(AnsiColors::RESET)
84
+ end
85
+
86
+ def bold
87
+ return maybe_colorize(AnsiColors::BOLD)
88
+ end
89
+
90
+ def dgray
91
+ return maybe_colorize(AnsiColors::DGRAY)
92
+ end
93
+
94
+ def red
95
+ return maybe_colorize(AnsiColors::RED)
96
+ end
97
+
98
+ def orange
99
+ return maybe_colorize(AnsiColors::ORANGE)
100
+ end
101
+
102
+ def green
103
+ return maybe_colorize(AnsiColors::GREEN)
104
+ end
105
+
106
+ def yellow
107
+ return maybe_colorize(AnsiColors::YELLOW)
108
+ end
109
+
110
+ def white
111
+ return maybe_colorize(AnsiColors::WHITE)
112
+ end
113
+
114
+ def black_bg
115
+ return maybe_colorize(AnsiColors::BLACK_BG)
116
+ end
117
+
118
+ def blue_bg
119
+ return maybe_colorize(AnsiColors::BLUE_BG)
120
+ end
121
+
122
+ def default_terminal_color
123
+ return maybe_colorize(AnsiColors::DEFAULT_TERMINAL_COLOR)
124
+ end
125
+
126
+ def ansi_colorize(text)
127
+ if should_output_color?
128
+ return AnsiColors.ansi_colorize(text)
129
+ else
130
+ return AnsiColors.strip_color_tags(text)
131
+ end
132
+ end
133
+
134
+ private
135
+ def maybe_colorize(ansi_color)
136
+ if should_output_color?
137
+ return ansi_color
138
+ else
139
+ return ""
140
+ end
141
+ end
142
+
143
+ def should_output_color?
144
+ if @enabled == :auto
145
+ return STDOUT.tty?
146
+ else
147
+ return @enabled
148
+ end
149
+ end
150
+ end
151
+
152
+ end # module Utils
153
153
  end # module PhusionPassenger
@@ -27,200 +27,200 @@ PhusionPassenger.require_passenger_lib 'utils/shellwords'
27
27
  require 'fileutils'
28
28
 
29
29
  module PhusionPassenger
30
- module Utils
31
-
32
- module Download
33
- extend self # Make methods available as class methods.
34
-
35
- def self.included(klass)
36
- # When included into another class, make sure that Utils
37
- # methods are made private.
38
- public_instance_methods(false).each do |method_name|
39
- klass.send(:private, method_name)
40
- end
41
- end
42
-
43
- # Downloads a file from the given URL and saves it to the given filename.
44
- # Returns whether the download succeeded.
45
- #
46
- # Options:
47
- #
48
- # show_progress: whether to show download progress. Default: false.
49
- # logger: the logger to use. If not given, this function will log to STDERR.
50
- # cacert: a CA certificate file to use for verifying SSL websites.
51
- # The default is to use the download tool's down CA database.
52
- # use_cache: Whether to copy the file from the download cache, if available.
53
- # Default: false.
54
- # connect_timeout: The maximum amount of time to spend on DNS lookup
55
- # and establishing the TCP connection. Set to nil to
56
- # disable this timeout. Default: 4.
57
- # idle_timeout: The maximum idle read time. Set to nil to set this timeout
58
- # to the default wget value, 900. Set to nil to disable this
59
- # timeout. Default: 5.
60
- # total_timeout: The maximum amount of time spent on the whole download
61
- # operation, including connection time. Only has effect on curl.
62
- # Set to nil to disable this timeout. Default: nil.
63
- def download(url, output, options = {})
64
- options = {
65
- :connect_timeout => 4,
66
- :idle_timeout => 5
67
- }.merge(options)
68
- logger = options[:logger] || Logger.new(STDERR)
69
-
70
- if options[:use_cache] && cache_dir = PhusionPassenger.download_cache_dir
71
- basename = basename_from_url(url)
72
- if File.exist?("#{cache_dir}/#{basename}")
73
- logger.info "Copying #{basename} from #{cache_dir}..."
74
- FileUtils.cp("#{cache_dir}/#{basename}", output)
75
- return true
76
- end
77
- end
78
-
79
- if PlatformInfo.find_command("curl")
80
- return download_with_curl(logger, url, output, options)
81
- elsif PlatformInfo.find_command("wget")
82
- return download_with_wget(logger, url, output, options)
83
- else
84
- logger.error "Could not download #{url}: no download tool found (curl or wget required)"
85
- return false
86
- end
87
- end
88
-
89
- private
90
- def basename_from_url(url)
91
- return url.sub(/.*\//, '')
92
- end
93
-
94
- def download_with_curl(logger, url, output, options)
95
- command = ["curl", "-f", "-L", "-o", output]
96
- if options[:show_progress]
97
- command << "-#"
98
- else
99
- command << "-s"
100
- command << "-S"
101
- end
102
- if options[:cacert]
103
- command << "--cacert"
104
- command << options[:cacert]
105
- end
106
- if options[:connect_timeout]
107
- command << "--connect-timeout"
108
- command << options[:connect_timeout].to_s
109
- end
110
- if options[:idle_timeout]
111
- command << "--speed-time"
112
- command << options[:idle_timeout].to_s
113
- command << "--speed-limit"
114
- command << "1"
115
- end
116
- if options[:total_timeout]
117
- command << "--max-time"
118
- command << options[:total_timeout].to_s
119
- end
120
- command << url
121
- command_str = Shellwords.join(command)
122
- logger.info("Invoking: #{command_str}")
123
-
124
- if options[:show_progress]
125
- # If curl errors out we don't want it to display 'curl: ' prefixes,
126
- # so we parse its output.
127
- begin
128
- io = IO.popen("#{command_str} 2>&1", "r")
129
- rescue SystemCallError => e
130
- logger.error("Could not invoke curl: #{e}")
131
- return false
132
- end
133
- begin
134
- non_empty_line_encountered = false
135
- while !io.eof?
136
- # We split on "\r" because progress bar lines do not contain "\n".
137
- data = io.gets("\r")
138
- data = remove_curl_output_prefix(data)
139
-
140
- # If an error occurs then the first few lines may be empty.
141
- # Skip those.
142
- if !non_empty_line_encountered && data =~ /\A\n+/
143
- data.gsub!(/\A\n+/, '')
144
- end
145
-
146
- non_empty_line_encountered = true
147
- STDERR.write(data)
148
- STDERR.flush
149
- end
150
- ensure
151
- io.close
152
- end
153
- result = $?.exitstatus == 0
154
- else
155
- begin
156
- output = `#{command_str} 2>&1`
157
- rescue SystemCallError => e
158
- logger.error("Could not invoke curl: #{e}")
159
- return false
160
- end
161
- result = $?.exitstatus == 0
162
- if !result
163
- output = remove_curl_output_prefix(output)
164
- output.chomp!
165
- logger.error("Could not download #{url}: #{output}")
166
- end
167
- end
168
-
169
- return result
170
- end
171
-
172
- def remove_curl_output_prefix(line)
173
- return line.gsub(/^curl: (\([0-9]+\) )?/, '')
174
- end
175
-
176
- def download_with_wget(logger, url, output, options)
177
- command = ["wget", "--tries=1", "-O", output]
178
- if !options[:show_progress]
179
- command << "-nv"
180
- end
181
- if options[:cacert]
182
- command << "--ca-certificate=#{options[:cacert]}"
183
- end
184
- if options[:connect_timeout]
185
- command << "--dns-timeout=#{options[:connect_timeout]}"
186
- command << "--connect-timeout=#{options[:connect_timeout]}"
187
- end
188
- if options[:idle_timeout]
189
- command << "--timeout=#{options[:idle_timeout]}"
190
- end
191
- command << url
192
- command_str = Shellwords.join(command)
193
- logger.info("Invoking: #{command_str}")
194
-
195
- if options[:show_progress]
196
- begin
197
- result = system(*command)
198
- rescue SystemCallError => e
199
- logger.error("Could not invoke wget: #{e}")
200
- return false
201
- end
202
- if !result
203
- logger.error("Could not download #{url}: #{output}")
204
- end
205
- else
206
- begin
207
- output = `#{command_str} 2>&1`
208
- rescue SystemCallError => e
209
- logger.error("Could not invoke wget: #{e}")
210
- return false
211
- end
212
- result = $?.exitstatus == 0
213
- if !result
214
- # Error output may begin with "<URL>:\n" which is redundant.
215
- output.gsub!(/\A#{Regexp.escape url}:\n/, '')
216
- output.chomp!
217
- logger.error("Could not download #{url}: #{output}")
218
- end
219
- end
220
-
221
- return result
222
- end
223
- end
224
-
225
- end # module Utils
30
+ module Utils
31
+
32
+ module Download
33
+ extend self # Make methods available as class methods.
34
+
35
+ def self.included(klass)
36
+ # When included into another class, make sure that Utils
37
+ # methods are made private.
38
+ public_instance_methods(false).each do |method_name|
39
+ klass.send(:private, method_name)
40
+ end
41
+ end
42
+
43
+ # Downloads a file from the given URL and saves it to the given filename.
44
+ # Returns whether the download succeeded.
45
+ #
46
+ # Options:
47
+ #
48
+ # show_progress: whether to show download progress. Default: false.
49
+ # logger: the logger to use. If not given, this function will log to STDERR.
50
+ # cacert: a CA certificate file to use for verifying SSL websites.
51
+ # The default is to use the download tool's down CA database.
52
+ # use_cache: Whether to copy the file from the download cache, if available.
53
+ # Default: false.
54
+ # connect_timeout: The maximum amount of time to spend on DNS lookup
55
+ # and establishing the TCP connection. Set to nil to
56
+ # disable this timeout. Default: 4.
57
+ # idle_timeout: The maximum idle read time. Set to nil to set this timeout
58
+ # to the default wget value, 900. Set to nil to disable this
59
+ # timeout. Default: 5.
60
+ # total_timeout: The maximum amount of time spent on the whole download
61
+ # operation, including connection time. Only has effect on curl.
62
+ # Set to nil to disable this timeout. Default: nil.
63
+ def download(url, output, options = {})
64
+ options = {
65
+ :connect_timeout => 4,
66
+ :idle_timeout => 5
67
+ }.merge(options)
68
+ logger = options[:logger] || Logger.new(STDERR)
69
+
70
+ if options[:use_cache] && cache_dir = PhusionPassenger.download_cache_dir
71
+ basename = basename_from_url(url)
72
+ if File.exist?("#{cache_dir}/#{basename}")
73
+ logger.info "Copying #{basename} from #{cache_dir}..."
74
+ FileUtils.cp("#{cache_dir}/#{basename}", output)
75
+ return true
76
+ end
77
+ end
78
+
79
+ if PlatformInfo.find_command("curl")
80
+ return download_with_curl(logger, url, output, options)
81
+ elsif PlatformInfo.find_command("wget")
82
+ return download_with_wget(logger, url, output, options)
83
+ else
84
+ logger.error "Could not download #{url}: no download tool found (curl or wget required)"
85
+ return false
86
+ end
87
+ end
88
+
89
+ private
90
+ def basename_from_url(url)
91
+ return url.sub(/.*\//, '')
92
+ end
93
+
94
+ def download_with_curl(logger, url, output, options)
95
+ command = ["curl", "-f", "-L", "-o", output]
96
+ if options[:show_progress]
97
+ command << "-#"
98
+ else
99
+ command << "-s"
100
+ command << "-S"
101
+ end
102
+ if options[:cacert]
103
+ command << "--cacert"
104
+ command << options[:cacert]
105
+ end
106
+ if options[:connect_timeout]
107
+ command << "--connect-timeout"
108
+ command << options[:connect_timeout].to_s
109
+ end
110
+ if options[:idle_timeout]
111
+ command << "--speed-time"
112
+ command << options[:idle_timeout].to_s
113
+ command << "--speed-limit"
114
+ command << "1"
115
+ end
116
+ if options[:total_timeout]
117
+ command << "--max-time"
118
+ command << options[:total_timeout].to_s
119
+ end
120
+ command << url
121
+ command_str = Shellwords.join(command)
122
+ logger.info("Invoking: #{command_str}")
123
+
124
+ if options[:show_progress]
125
+ # If curl errors out we don't want it to display 'curl: ' prefixes,
126
+ # so we parse its output.
127
+ begin
128
+ io = IO.popen("#{command_str} 2>&1", "r")
129
+ rescue SystemCallError => e
130
+ logger.error("Could not invoke curl: #{e}")
131
+ return false
132
+ end
133
+ begin
134
+ non_empty_line_encountered = false
135
+ while !io.eof?
136
+ # We split on "\r" because progress bar lines do not contain "\n".
137
+ data = io.gets("\r")
138
+ data = remove_curl_output_prefix(data)
139
+
140
+ # If an error occurs then the first few lines may be empty.
141
+ # Skip those.
142
+ if !non_empty_line_encountered && data =~ /\A\n+/
143
+ data.gsub!(/\A\n+/, '')
144
+ end
145
+
146
+ non_empty_line_encountered = true
147
+ STDERR.write(data)
148
+ STDERR.flush
149
+ end
150
+ ensure
151
+ io.close
152
+ end
153
+ result = $?.exitstatus == 0
154
+ else
155
+ begin
156
+ output = `#{command_str} 2>&1`
157
+ rescue SystemCallError => e
158
+ logger.error("Could not invoke curl: #{e}")
159
+ return false
160
+ end
161
+ result = $?.exitstatus == 0
162
+ if !result
163
+ output = remove_curl_output_prefix(output)
164
+ output.chomp!
165
+ logger.error("Could not download #{url}: #{output}")
166
+ end
167
+ end
168
+
169
+ return result
170
+ end
171
+
172
+ def remove_curl_output_prefix(line)
173
+ return line.gsub(/^curl: (\([0-9]+\) )?/, '')
174
+ end
175
+
176
+ def download_with_wget(logger, url, output, options)
177
+ command = ["wget", "--tries=1", "-O", output]
178
+ if !options[:show_progress]
179
+ command << "-nv"
180
+ end
181
+ if options[:cacert]
182
+ command << "--ca-certificate=#{options[:cacert]}"
183
+ end
184
+ if options[:connect_timeout]
185
+ command << "--dns-timeout=#{options[:connect_timeout]}"
186
+ command << "--connect-timeout=#{options[:connect_timeout]}"
187
+ end
188
+ if options[:idle_timeout]
189
+ command << "--timeout=#{options[:idle_timeout]}"
190
+ end
191
+ command << url
192
+ command_str = Shellwords.join(command)
193
+ logger.info("Invoking: #{command_str}")
194
+
195
+ if options[:show_progress]
196
+ begin
197
+ result = system(*command)
198
+ rescue SystemCallError => e
199
+ logger.error("Could not invoke wget: #{e}")
200
+ return false
201
+ end
202
+ if !result
203
+ logger.error("Could not download #{url}: #{output}")
204
+ end
205
+ else
206
+ begin
207
+ output = `#{command_str} 2>&1`
208
+ rescue SystemCallError => e
209
+ logger.error("Could not invoke wget: #{e}")
210
+ return false
211
+ end
212
+ result = $?.exitstatus == 0
213
+ if !result
214
+ # Error output may begin with "<URL>:\n" which is redundant.
215
+ output.gsub!(/\A#{Regexp.escape url}:\n/, '')
216
+ output.chomp!
217
+ logger.error("Could not download #{url}: #{output}")
218
+ end
219
+ end
220
+
221
+ return result
222
+ end
223
+ end
224
+
225
+ end # module Utils
226
226
  end # module PhusionPassenger