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
@@ -24,163 +24,163 @@
24
24
  PhusionPassenger.require_passenger_lib 'native_support'
25
25
 
26
26
  module PhusionPassenger
27
- module Utils
27
+ module Utils
28
28
 
29
- # Watches changes on one or more files or directories. To use this class,
30
- # construct an object, passing it file or directory names to watch, then
31
- # call #wait_for_change. #wait_for_change waits until one of the following
32
- # events has happened since the constructor was called:
33
- #
34
- # - One of the specified files has been renamed, deleted, or its access
35
- # revoked. This will cause +true+ to be returned.
36
- # - One of the specified directories has been modified, renamed, deleted,
37
- # or its access revoked. This will cause +true+ to be returned.
38
- # - +termination_pipe+ (as passed to the constructor) becomes readable.
39
- # This will cause +nil+ to be returned.
40
- # - The thread is interrupted. This will cause +nil+ to be returned.
41
- #
42
- # The constructor will attempt to stat and possibly also open all specified
43
- # files/directories. If one of them cannot be statted or opened, then
44
- # +false+ will be returned by #wait_for_change.
45
- #
46
- # #wait_for_change may only be called once. After calling it one should
47
- # create a new object if one wishes to watch the filesystem again.
48
- #
49
- # Always call #close when a FileSystemWatcher object is no longer needed
50
- # in order to free resources.
51
- #
52
- # This class tries to use kqueue for efficient filesystem watching on
53
- # platforms that support it. On other platforms it'll fallback to stat
54
- # polling instead.
55
-
56
- if defined?(NativeSupport::FileSystemWatcher)
57
- FileSystemWatcher = NativeSupport::FileSystemWatcher
58
-
59
- FileSystemWatcher.class_eval do
60
- def self.new(filenames, termination_pipe = nil)
61
- # Default parameter values, type conversion and exception
62
- # handling in C is too much of a pain.
63
- filenames = filenames.map do |filename|
64
- filename.to_s
65
- end
66
- return _new(filenames, termination_pipe)
67
- end
68
-
69
- def self.opens_files?
70
- return true
71
- end
72
- end
73
- else
74
- class FileSystemWatcher
75
- attr_accessor :poll_interval
76
-
77
- def self.opens_files?
78
- return false
79
- end
80
-
81
- def initialize(filenames, termination_pipe = nil)
82
- @poll_interval = 3
83
- @termination_pipe = termination_pipe
84
- @dirs = []
85
- @files = []
86
-
87
- begin
88
- filenames.each do |filename|
89
- stat = File.stat(filename)
90
- if stat.directory?
91
- @dirs << DirInfo.new(filename, stat)
92
- else
93
- @files << FileInfo.new(filename, stat)
94
- end
95
- end
96
- rescue Errno::EACCES, Errno::ENOENT
97
- @dirs = @files = nil
98
- end
99
- end
100
-
101
- def wait_for_change
102
- if !@dirs
103
- return false
104
- end
105
-
106
- while true
107
- if changed?
108
- return true
109
- elsif select([@termination_pipe], nil, nil, @poll_interval)
110
- return nil
111
- end
112
- end
113
- end
114
-
115
- def close
116
- end
117
-
118
- private
119
- class DirInfo
120
- DOT = "."
121
- DOTDOT = ".."
122
-
123
- def initialize(filename, stat)
124
- @filename = filename
125
- @stat = stat
126
- @subfiles = {}
127
- Dir.foreach(filename) do |entry|
128
- next if entry == DOT || entry == DOTDOT
129
- subfilename = "#{filename}/#{entry}"
130
- @subfiles[entry] = FileInfo.new(subfilename, File.stat(subfilename))
131
- end
132
- end
133
-
134
- def changed?
135
- new_stat = File.stat(@filename)
136
- if @stat.ino != new_stat.ino || !new_stat.directory? || @stat.mtime != new_stat.mtime
137
- return true
138
- end
139
-
140
- count = 0
141
- Dir.foreach(@filename) do |entry|
142
- next if entry == DOT || entry == DOTDOT
143
- subfilename = "#{@filename}/#{entry}"
144
-
145
- file_info = @subfiles[entry]
146
- if !file_info || file_info.changed?(false)
147
- return true
148
- else
149
- count += 1
150
- end
151
- end
152
-
153
- return count != @subfiles.size
154
- rescue Errno::EACCES, Errno::ENOENT
155
- return true
156
- end
157
- end
158
-
159
- class FileInfo
160
- def initialize(filename, stat)
161
- @filename = filename
162
- @stat = stat
163
- end
164
-
165
- def changed?(check_mtime = true)
166
- new_stat = File.stat(@filename)
167
- if check_mtime
168
- mtime_changed = @stat.mtime != new_stat.mtime || @stat.size != new_stat.size
169
- else
170
- mtime_changed = false
171
- end
172
- return @stat.ino != new_stat.ino || @stat.ftype != new_stat.ftype || mtime_changed
173
- rescue Errno::EACCES, Errno::ENOENT
174
- return true
175
- end
176
- end
177
-
178
- def changed?
179
- return @dirs.any? { |dir_info| dir_info.changed? } ||
180
- @files.any? { |file_info| file_info.changed? }
181
- end
182
- end
183
- end
184
-
185
- end # module Utils
29
+ # Watches changes on one or more files or directories. To use this class,
30
+ # construct an object, passing it file or directory names to watch, then
31
+ # call #wait_for_change. #wait_for_change waits until one of the following
32
+ # events has happened since the constructor was called:
33
+ #
34
+ # - One of the specified files has been renamed, deleted, or its access
35
+ # revoked. This will cause +true+ to be returned.
36
+ # - One of the specified directories has been modified, renamed, deleted,
37
+ # or its access revoked. This will cause +true+ to be returned.
38
+ # - +termination_pipe+ (as passed to the constructor) becomes readable.
39
+ # This will cause +nil+ to be returned.
40
+ # - The thread is interrupted. This will cause +nil+ to be returned.
41
+ #
42
+ # The constructor will attempt to stat and possibly also open all specified
43
+ # files/directories. If one of them cannot be statted or opened, then
44
+ # +false+ will be returned by #wait_for_change.
45
+ #
46
+ # #wait_for_change may only be called once. After calling it one should
47
+ # create a new object if one wishes to watch the filesystem again.
48
+ #
49
+ # Always call #close when a FileSystemWatcher object is no longer needed
50
+ # in order to free resources.
51
+ #
52
+ # This class tries to use kqueue for efficient filesystem watching on
53
+ # platforms that support it. On other platforms it'll fallback to stat
54
+ # polling instead.
55
+
56
+ if defined?(NativeSupport::FileSystemWatcher)
57
+ FileSystemWatcher = NativeSupport::FileSystemWatcher
58
+
59
+ FileSystemWatcher.class_eval do
60
+ def self.new(filenames, termination_pipe = nil)
61
+ # Default parameter values, type conversion and exception
62
+ # handling in C is too much of a pain.
63
+ filenames = filenames.map do |filename|
64
+ filename.to_s
65
+ end
66
+ return _new(filenames, termination_pipe)
67
+ end
68
+
69
+ def self.opens_files?
70
+ return true
71
+ end
72
+ end
73
+ else
74
+ class FileSystemWatcher
75
+ attr_accessor :poll_interval
76
+
77
+ def self.opens_files?
78
+ return false
79
+ end
80
+
81
+ def initialize(filenames, termination_pipe = nil)
82
+ @poll_interval = 3
83
+ @termination_pipe = termination_pipe
84
+ @dirs = []
85
+ @files = []
86
+
87
+ begin
88
+ filenames.each do |filename|
89
+ stat = File.stat(filename)
90
+ if stat.directory?
91
+ @dirs << DirInfo.new(filename, stat)
92
+ else
93
+ @files << FileInfo.new(filename, stat)
94
+ end
95
+ end
96
+ rescue Errno::EACCES, Errno::ENOENT
97
+ @dirs = @files = nil
98
+ end
99
+ end
100
+
101
+ def wait_for_change
102
+ if !@dirs
103
+ return false
104
+ end
105
+
106
+ while true
107
+ if changed?
108
+ return true
109
+ elsif select([@termination_pipe], nil, nil, @poll_interval)
110
+ return nil
111
+ end
112
+ end
113
+ end
114
+
115
+ def close
116
+ end
117
+
118
+ private
119
+ class DirInfo
120
+ DOT = "."
121
+ DOTDOT = ".."
122
+
123
+ def initialize(filename, stat)
124
+ @filename = filename
125
+ @stat = stat
126
+ @subfiles = {}
127
+ Dir.foreach(filename) do |entry|
128
+ next if entry == DOT || entry == DOTDOT
129
+ subfilename = "#{filename}/#{entry}"
130
+ @subfiles[entry] = FileInfo.new(subfilename, File.stat(subfilename))
131
+ end
132
+ end
133
+
134
+ def changed?
135
+ new_stat = File.stat(@filename)
136
+ if @stat.ino != new_stat.ino || !new_stat.directory? || @stat.mtime != new_stat.mtime
137
+ return true
138
+ end
139
+
140
+ count = 0
141
+ Dir.foreach(@filename) do |entry|
142
+ next if entry == DOT || entry == DOTDOT
143
+ subfilename = "#{@filename}/#{entry}"
144
+
145
+ file_info = @subfiles[entry]
146
+ if !file_info || file_info.changed?(false)
147
+ return true
148
+ else
149
+ count += 1
150
+ end
151
+ end
152
+
153
+ return count != @subfiles.size
154
+ rescue Errno::EACCES, Errno::ENOENT
155
+ return true
156
+ end
157
+ end
158
+
159
+ class FileInfo
160
+ def initialize(filename, stat)
161
+ @filename = filename
162
+ @stat = stat
163
+ end
164
+
165
+ def changed?(check_mtime = true)
166
+ new_stat = File.stat(@filename)
167
+ if check_mtime
168
+ mtime_changed = @stat.mtime != new_stat.mtime || @stat.size != new_stat.size
169
+ else
170
+ mtime_changed = false
171
+ end
172
+ return @stat.ino != new_stat.ino || @stat.ftype != new_stat.ftype || mtime_changed
173
+ rescue Errno::EACCES, Errno::ENOENT
174
+ return true
175
+ end
176
+ end
177
+
178
+ def changed?
179
+ return @dirs.any? { |dir_info| dir_info.changed? } ||
180
+ @files.any? { |file_info| file_info.changed? }
181
+ end
182
+ end
183
+ end
184
+
185
+ end # module Utils
186
186
  end # module PhusionPassenger
@@ -25,108 +25,108 @@
25
25
  PhusionPassenger.require_passenger_lib 'platform_info/operating_system'
26
26
 
27
27
  module PhusionPassenger
28
- module Utils
28
+ module Utils
29
29
 
30
- # A /etc/hosts parser. Also supports writing groups of data to the file.
31
- class HostsFileParser
32
- def self.flush_dns_cache!
33
- if PlatformInfo.os_name == "macosx"
34
- system("dscacheutil -flushcache")
35
- end
36
- end
37
-
38
- def initialize(filename_or_io = "/etc/hosts")
39
- if filename_or_io.respond_to?(:readline)
40
- read_and_parse(filename_or_io)
41
- else
42
- File.open(filename_or_io, "rb") do |f|
43
- read_and_parse(f)
44
- end
45
- end
46
- end
47
-
48
- def ip_count
49
- return @ips.size
50
- end
51
-
52
- def host_count
53
- return @host_names.size
54
- end
55
-
56
- def resolve(host_name)
57
- if host_name.downcase == "localhost"
58
- return "127.0.0.1"
59
- else
60
- return @host_names[host_name.downcase]
61
- end
62
- end
63
-
64
- def resolves_to_localhost?(hostname)
65
- ip = resolve(hostname)
66
- return ip == "127.0.0.1" || ip == "::1" || ip == "0.0.0.0"
67
- end
68
-
69
- def add_group_data(marker, data)
70
- begin_index = find_line(0, "###### BEGIN #{marker} ######")
71
- end_index = find_line(begin_index + 1, "###### END #{marker} ######") if begin_index
72
- if begin_index && end_index
73
- @lines[begin_index + 1 .. end_index - 1] = data.split("\n")
74
- else
75
- @lines << "###### BEGIN #{marker} ######"
76
- @lines.concat(data.split("\n"))
77
- @lines << "###### END #{marker} ######"
78
- end
79
- end
80
-
81
- def write(io)
82
- @lines.each do |line|
83
- io.puts(line)
84
- end
85
- end
30
+ # A /etc/hosts parser. Also supports writing groups of data to the file.
31
+ class HostsFileParser
32
+ def self.flush_dns_cache!
33
+ if PlatformInfo.os_name == "macosx"
34
+ system("dscacheutil -flushcache")
35
+ end
36
+ end
86
37
 
87
- private
88
- def read_and_parse(io)
89
- lines = []
90
- ips = {}
91
- all_host_names = {}
92
- while !io.eof?
93
- line = io.readline
94
- line.sub!(/\n\Z/m, '')
95
- lines << line
96
- ip, host_names = parse_line(line)
97
- if ip
98
- ips[ip] ||= []
99
- ips[ip].concat(host_names)
100
- host_names.each do |host_name|
101
- all_host_names[host_name.downcase] = ip
102
- end
103
- end
104
- end
105
- @lines = lines
106
- @ips = ips
107
- @host_names = all_host_names
108
- end
109
-
110
- def parse_line(line)
111
- return nil if line =~ /^[\s\t]*#/
112
- line = line.strip
113
- return nil if line.empty?
114
- ip, *host_names = line.split(/[ \t]+/)
115
- return [ip, host_names]
116
- end
117
-
118
- def find_line(start_index, content)
119
- i = start_index
120
- while i < @lines.size
121
- if @lines[i] == content
122
- return i
123
- else
124
- i += 1
125
- end
126
- end
127
- return nil
128
- end
129
- end
38
+ def initialize(filename_or_io = "/etc/hosts")
39
+ if filename_or_io.respond_to?(:readline)
40
+ read_and_parse(filename_or_io)
41
+ else
42
+ File.open(filename_or_io, "rb") do |f|
43
+ read_and_parse(f)
44
+ end
45
+ end
46
+ end
130
47
 
131
- end
48
+ def ip_count
49
+ return @ips.size
50
+ end
51
+
52
+ def host_count
53
+ return @host_names.size
54
+ end
55
+
56
+ def resolve(host_name)
57
+ if host_name.downcase == "localhost"
58
+ return "127.0.0.1"
59
+ else
60
+ return @host_names[host_name.downcase]
61
+ end
62
+ end
63
+
64
+ def resolves_to_localhost?(hostname)
65
+ ip = resolve(hostname)
66
+ return ip == "127.0.0.1" || ip == "::1" || ip == "0.0.0.0"
67
+ end
68
+
69
+ def add_group_data(marker, data)
70
+ begin_index = find_line(0, "###### BEGIN #{marker} ######")
71
+ end_index = find_line(begin_index + 1, "###### END #{marker} ######") if begin_index
72
+ if begin_index && end_index
73
+ @lines[begin_index + 1 .. end_index - 1] = data.split("\n")
74
+ else
75
+ @lines << "###### BEGIN #{marker} ######"
76
+ @lines.concat(data.split("\n"))
77
+ @lines << "###### END #{marker} ######"
78
+ end
79
+ end
80
+
81
+ def write(io)
82
+ @lines.each do |line|
83
+ io.puts(line)
84
+ end
85
+ end
86
+
87
+ private
88
+ def read_and_parse(io)
89
+ lines = []
90
+ ips = {}
91
+ all_host_names = {}
92
+ while !io.eof?
93
+ line = io.readline
94
+ line.sub!(/\n\Z/m, '')
95
+ lines << line
96
+ ip, host_names = parse_line(line)
97
+ if ip
98
+ ips[ip] ||= []
99
+ ips[ip].concat(host_names)
100
+ host_names.each do |host_name|
101
+ all_host_names[host_name.downcase] = ip
102
+ end
103
+ end
104
+ end
105
+ @lines = lines
106
+ @ips = ips
107
+ @host_names = all_host_names
108
+ end
109
+
110
+ def parse_line(line)
111
+ return nil if line =~ /^[\s\t]*#/
112
+ line = line.strip
113
+ return nil if line.empty?
114
+ ip, *host_names = line.split(/[ \t]+/)
115
+ return [ip, host_names]
116
+ end
117
+
118
+ def find_line(start_index, content)
119
+ i = start_index
120
+ while i < @lines.size
121
+ if @lines[i] == content
122
+ return i
123
+ else
124
+ i += 1
125
+ end
126
+ end
127
+ return nil
128
+ end
129
+ end
130
+
131
+ end
132
132
  end