passenger 4.0.33 → 4.0.34
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 +15 -0
- checksums.yaml.gz.asc +12 -0
- data.tar.gz.asc +7 -7
- data/NEWS +60 -0
- data/bin/passenger-config +1 -1
- data/bin/passenger-install-apache2-module +510 -40
- data/bin/passenger-install-nginx-module +26 -2
- data/build/cxx_tests.rb +1 -1
- data/build/documentation.rb +19 -21
- data/build/integration_tests.rb +39 -12
- data/build/misc.rb +18 -0
- data/build/packaging.rb +116 -56
- data/build/rpm.rb +20 -11
- data/build/ruby_tests.rb +2 -3
- data/build/test_basics.rb +9 -0
- data/debian.template/passenger.conf +2 -0
- data/debian.template/passenger.load +2 -0
- data/dev/run_travis.sh +3 -5
- data/dev/test_rpm_packaging.sh +28 -0
- data/doc/Users guide Apache.idmap.txt +6 -4
- data/doc/users_guide_snippets/installation.txt +20 -2
- data/doc/users_guide_snippets/tips.txt +1 -1
- data/ext/common/ApplicationPool2/Pool.h +1 -1
- data/ext/common/Constants.h +5 -1
- data/ext/common/agents/HelperAgent/RequestHandler.h +1 -1
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +20 -0
- data/ext/common/agents/Watchdog/Main.cpp +10 -0
- data/ext/ruby/passenger_native_support.c +23 -11
- data/helper-scripts/classic-rails-loader.rb +9 -3
- data/helper-scripts/classic-rails-preloader.rb +10 -4
- data/helper-scripts/download_binaries/extconf.rb +46 -22
- data/helper-scripts/meteor-loader.rb +0 -1
- data/helper-scripts/node-loader.js +2 -1
- data/helper-scripts/prespawn +7 -1
- data/helper-scripts/rack-loader.rb +32 -3
- data/helper-scripts/rack-preloader.rb +10 -4
- data/lib/phusion_passenger.rb +40 -21
- data/lib/phusion_passenger/abstract_installer.rb +7 -4
- data/lib/phusion_passenger/analytics_logger.rb +4 -3
- data/lib/phusion_passenger/config/about_command.rb +27 -6
- data/lib/phusion_passenger/{config.rb → config/main.rb} +3 -2
- data/lib/phusion_passenger/config/restart_app_command.rb +1 -1
- data/lib/phusion_passenger/config/validate_install_command.rb +231 -0
- data/lib/phusion_passenger/constants.rb +2 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +92 -19
- data/lib/phusion_passenger/native_support.rb +33 -11
- data/lib/phusion_passenger/packaging.rb +1 -0
- data/lib/phusion_passenger/platform_info.rb +5 -2
- data/lib/phusion_passenger/platform_info/apache.rb +229 -60
- data/lib/phusion_passenger/platform_info/apache_detector.rb +26 -31
- data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +4 -4
- data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +4 -4
- data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +1 -1
- data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +1 -1
- data/lib/phusion_passenger/platform_info/linux.rb +2 -1
- data/lib/phusion_passenger/platform_info/ruby.rb +7 -0
- data/lib/phusion_passenger/preloader_shared_helpers.rb +2 -1
- data/lib/phusion_passenger/request_handler.rb +2 -1
- data/lib/phusion_passenger/request_handler/thread_handler.rb +2 -1
- data/lib/phusion_passenger/standalone/runtime_installer.rb +35 -13
- data/lib/phusion_passenger/standalone/start_command.rb +2 -2
- data/lib/phusion_passenger/utils.rb +1 -23
- data/lib/phusion_passenger/utils/ansi_colors.rb +7 -1
- data/lib/phusion_passenger/utils/download.rb +36 -2
- data/lib/phusion_passenger/utils/native_support_utils.rb +65 -0
- data/resources/templates/apache2/apache_install_broken.txt.erb +20 -0
- data/resources/templates/apache2/config_snippets.txt.erb +2 -4
- data/resources/templates/apache2/present_choice_for_no_update_config.txt.erb +5 -0
- data/resources/templates/installer_common/cannot_access_files_as_root.txt.erb +15 -0
- data/resources/templates/installer_common/run_installer_as_root.txt.erb +6 -3
- data/resources/templates/nginx/nginx_module_sources_not_available.txt.erb +1 -1
- data/resources/templates/nginx/other_nginx_installations_exist.txt.erb +17 -0
- data/rpm/apache-passenger.conf.in +26 -0
- data/rpm/config.json +30 -0
- data/rpm/passenger.logrotate +7 -0
- data/rpm/passenger.spec.template +456 -0
- data/rpm/passenger_dynamic_thread_group.patch +16 -0
- data/rpm/passenger_tests_default_config_example.patch +44 -0
- data/rpm/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +21 -0
- data/rpm/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +45 -0
- data/test/config.json.rpm-automation +15 -0
- data/test/integration_tests/downloaded_binaries_tests.rb +80 -2
- data/test/integration_tests/native_packaging_spec.rb +136 -44
- data/test/integration_tests/standalone_tests.rb +2 -11
- data/test/ruby/analytics_logger_spec.rb +65 -19
- data/test/ruby/utils_spec.rb +2 -0
- metadata +532 -548
- metadata.gz.asc +7 -7
- data/resources/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -9
- data/rpm/README.rdoc +0 -117
- data/rpm/config/apache-passenger.conf.in +0 -19
- data/rpm/config/nginx-passenger.conf.in +0 -10
- data/rpm/config/rubygem-passenger.te +0 -10
- data/rpm/doc/README.nginx-alternatives +0 -5
- data/rpm/doc/example_yum_repository_htaccess +0 -5
- data/rpm/doc/footer.shtml +0 -12
- data/rpm/doc/header.shtml +0 -156
- data/rpm/nginx-alternatives.spec +0 -97
- data/rpm/passenger-release.spec +0 -91
- data/rpm/passenger.spec +0 -667
- data/rpm/patches/passenger-force-native.patch +0 -63
- data/rpm/release/RPM-GPG-KEY-stealthymonkeys +0 -33
- data/rpm/release/build-release.sh +0 -35
- data/rpm/release/build.rb +0 -301
- data/rpm/release/create-mirrors.sh +0 -16
- data/rpm/release/mirrors +0 -1
- data/rpm/release/mock-repo/comps.xml +0 -21
- data/rpm/release/mock-repo/rubygem-daemon_controller-0.2.5-1.noarch.rpm +0 -0
- data/rpm/release/mock-repo/rubygem-file-tail-1.0.5-1.noarch.rpm +0 -0
- data/rpm/release/mock-repo/rubygem-spruz-0.2.2-1.noarch.rpm +0 -0
- data/rpm/release/mocksetup-first.sh +0 -102
- data/rpm/release/mocksetup.sh +0 -67
@@ -40,9 +40,13 @@ class NativeSupportLoader
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def start
|
43
|
-
if
|
43
|
+
if ENV['PASSENGER_USE_RUBY_NATIVE_SUPPORT'] == '0'
|
44
|
+
STDERR.puts " --> Continuing without #{library_name}."
|
45
|
+
STDERR.puts " Because PASSENGER_USE_RUBY_NATIVE_SUPPORT is set to 0."
|
46
|
+
return false
|
47
|
+
elsif try_load
|
44
48
|
return true
|
45
|
-
elsif
|
49
|
+
elsif compile_and_load || download_binary_and_load
|
46
50
|
STDERR.puts " --> #{library_name} successfully loaded."
|
47
51
|
return true
|
48
52
|
else
|
@@ -139,10 +143,11 @@ private
|
|
139
143
|
PhusionPassenger.require_passenger_lib 'platform_info/ruby'
|
140
144
|
PhusionPassenger.require_passenger_lib 'utils/tmpio'
|
141
145
|
PhusionPassenger.require_passenger_lib 'utils/download'
|
146
|
+
|
142
147
|
PhusionPassenger::Utils.mktmpdir("passenger-native-support-") do |dir|
|
143
148
|
Dir.chdir(dir) do
|
144
149
|
basename = "rubyext-#{archdir}.tar.gz"
|
145
|
-
if !download(basename, dir)
|
150
|
+
if !download(basename, dir, :total_timeout => 30)
|
146
151
|
return false
|
147
152
|
end
|
148
153
|
|
@@ -234,16 +239,33 @@ private
|
|
234
239
|
return target_dirs
|
235
240
|
end
|
236
241
|
|
237
|
-
def download(name, output_dir)
|
238
|
-
url = "#{PhusionPassenger::BINARIES_URL_ROOT}/#{PhusionPassenger::VERSION_STRING}/#{name}"
|
239
|
-
filename = "#{output_dir}/#{name}"
|
242
|
+
def download(name, output_dir, options = {})
|
240
243
|
logger = Logger.new(STDERR)
|
241
244
|
logger.level = Logger::WARN
|
242
|
-
logger.formatter = proc
|
243
|
-
|
244
|
-
|
245
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
246
|
+
msg.gsub(/^/, " ") + "\n"
|
247
|
+
end
|
248
|
+
sites = PhusionPassenger.binaries_sites
|
249
|
+
sites.each_with_index do |site, i|
|
250
|
+
if real_download(site, name, output_dir, logger, options)
|
251
|
+
logger.warn "Download OK!" if i > 0
|
252
|
+
return true
|
253
|
+
elsif i != sites.size - 1
|
254
|
+
logger.warn "Trying next mirror..."
|
255
|
+
end
|
256
|
+
end
|
257
|
+
return false
|
258
|
+
end
|
259
|
+
|
260
|
+
def real_download(site, name, output_dir, logger, options)
|
261
|
+
url = "#{site[:url]}/#{VERSION_STRING}/#{name}"
|
262
|
+
filename = "#{output_dir}/#{name}"
|
263
|
+
real_options = options.merge(
|
264
|
+
:cacert => site[:cacert],
|
245
265
|
:use_cache => true,
|
246
|
-
:logger => logger
|
266
|
+
:logger => logger
|
267
|
+
)
|
268
|
+
return PhusionPassenger::Utils::Download.download(url, filename, real_options)
|
247
269
|
end
|
248
270
|
|
249
271
|
def mkdir(dir)
|
@@ -265,7 +287,7 @@ private
|
|
265
287
|
PhusionPassenger::Utils.mktmpdir("passenger-native-support-") do |tmpdir|
|
266
288
|
s_tmpdir = Shellwords.escape(tmpdir)
|
267
289
|
result = system("#{command_string} >#{s_tmpdir}/log 2>&1")
|
268
|
-
system("cat #{s_tmpdir}/log | sed 's/^/ /'")
|
290
|
+
system("cat #{s_tmpdir}/log | sed 's/^/ /' >&2")
|
269
291
|
return result
|
270
292
|
end
|
271
293
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
+
# encoding: binary
|
1
2
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
-
# Copyright (c) 2010-
|
3
|
+
# Copyright (c) 2010-2014 Phusion
|
3
4
|
#
|
4
5
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
5
6
|
#
|
@@ -218,7 +219,9 @@ public
|
|
218
219
|
end
|
219
220
|
|
220
221
|
def self.read_file(filename)
|
221
|
-
return File.
|
222
|
+
return File.open(filename, "rb") do |f|
|
223
|
+
f.read
|
224
|
+
end
|
222
225
|
rescue
|
223
226
|
return ""
|
224
227
|
end
|
@@ -101,6 +101,27 @@ module PlatformInfo
|
|
101
101
|
end
|
102
102
|
memoize :httpd_version
|
103
103
|
|
104
|
+
# Run `httpd -V` and return its output. On some systems, such as Ubuntu 13.10,
|
105
|
+
# `httpd -V` fails without the environment variables defined in various scripts.
|
106
|
+
# Here we take care of evaluating those scripts before running `httpd -V`.
|
107
|
+
def self.httpd_V(options = nil)
|
108
|
+
if options
|
109
|
+
httpd = options[:httpd] || self.httpd(options)
|
110
|
+
else
|
111
|
+
httpd = self.httpd
|
112
|
+
end
|
113
|
+
if httpd
|
114
|
+
command = "#{httpd} -V"
|
115
|
+
if envvars_file = httpd_envvars_file(options)
|
116
|
+
command = ". '#{envvars_file}' && #{command}"
|
117
|
+
end
|
118
|
+
return `#{command}`
|
119
|
+
else
|
120
|
+
return nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
memoize :httpd_V
|
124
|
+
|
104
125
|
# The Apache executable's architectural bits. Returns 32 or 64,
|
105
126
|
# or nil if unable to detect.
|
106
127
|
def self.httpd_architecture_bits(options = nil)
|
@@ -125,27 +146,38 @@ module PlatformInfo
|
|
125
146
|
end
|
126
147
|
memoize :httpd_architecture_bits
|
127
148
|
|
128
|
-
# The Apache root directory.
|
129
|
-
|
130
|
-
|
149
|
+
# The default Apache root directory, as specified by its compilation parameters.
|
150
|
+
# This may be different from the value of the ServerRoot directive.
|
151
|
+
def self.httpd_default_root(options = nil)
|
152
|
+
if options
|
153
|
+
info = httpd_V(options)
|
154
|
+
else
|
155
|
+
info = httpd_V
|
156
|
+
end
|
157
|
+
if info
|
131
158
|
info =~ / -D HTTPD_ROOT="(.+)"$/
|
132
159
|
return $1
|
133
160
|
else
|
134
161
|
return nil
|
135
162
|
end
|
136
163
|
end
|
137
|
-
memoize :
|
164
|
+
memoize :httpd_default_root
|
138
165
|
|
139
166
|
# The default Apache configuration file, or nil if Apache is not found.
|
140
167
|
def self.httpd_default_config_file(options = nil)
|
141
|
-
if
|
168
|
+
if options
|
169
|
+
info = httpd_V(options)
|
170
|
+
else
|
171
|
+
info = httpd_V
|
172
|
+
end
|
173
|
+
if info
|
142
174
|
info =~ /-D SERVER_CONFIG_FILE="(.+)"$/
|
143
175
|
filename = $1
|
144
176
|
if filename =~ /\A\//
|
145
177
|
return filename
|
146
178
|
else
|
147
|
-
# Not an absolute path. Infer from root.
|
148
|
-
if root =
|
179
|
+
# Not an absolute path. Infer from default root.
|
180
|
+
if root = httpd_default_root(options)
|
149
181
|
return "#{root}/#{filename}"
|
150
182
|
else
|
151
183
|
return nil
|
@@ -157,6 +189,26 @@ module PlatformInfo
|
|
157
189
|
end
|
158
190
|
memoize :httpd_default_config_file
|
159
191
|
|
192
|
+
# Given an Apache config file, returns the a hash with the following elements:
|
193
|
+
#
|
194
|
+
# * `:files` - An array containing `config_file`, as well as all config files
|
195
|
+
# included from that config file, including recursively included
|
196
|
+
# ones. Only filenames that actually exist are put here.
|
197
|
+
# * `:unreadable_files` - All config files that this function was unable
|
198
|
+
# to read.
|
199
|
+
def self.httpd_included_config_files(config_file, options = nil)
|
200
|
+
state = {
|
201
|
+
:files => { config_file => true },
|
202
|
+
:unreadable_files => [],
|
203
|
+
:root => httpd_default_root(options)
|
204
|
+
}
|
205
|
+
scan_for_included_apache2_config_files(config_file, state, options)
|
206
|
+
return {
|
207
|
+
:files => state[:files].keys,
|
208
|
+
:unreadable_files => state[:unreadable_files]
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
160
212
|
# The default Apache error log's filename, as it is compiled into the Apache
|
161
213
|
# main executable. This may not be the actual error log that is used. The actual
|
162
214
|
# error log depends on the configuration file.
|
@@ -170,8 +222,8 @@ module PlatformInfo
|
|
170
222
|
if filename =~ /\A\//
|
171
223
|
return filename
|
172
224
|
else
|
173
|
-
# Not an absolute path. Infer from root.
|
174
|
-
if root =
|
225
|
+
# Not an absolute path. Infer from default root.
|
226
|
+
if root = httpd_default_root(options)
|
175
227
|
return "#{root}/#{filename}"
|
176
228
|
else
|
177
229
|
return nil
|
@@ -188,35 +240,16 @@ module PlatformInfo
|
|
188
240
|
begin
|
189
241
|
contents = File.open(config_file, "rb") { |f| f.read }
|
190
242
|
rescue Errno::EACCES
|
243
|
+
log "Unable to open #{config_file} for reading"
|
191
244
|
return nil
|
192
245
|
end
|
193
246
|
# We don't want to match comments
|
194
247
|
contents.gsub!(/^[ \t]*#.*/, '')
|
195
|
-
if contents =~ /^ErrorLog (.+)
|
196
|
-
filename = $1
|
197
|
-
if filename
|
198
|
-
log "Error log seems to be located in \"#{filename}\", " +
|
199
|
-
"but value contains environment variables. " +
|
200
|
-
"Attempting to substitute them..."
|
201
|
-
end
|
202
|
-
# The Apache config file supports environment variable
|
203
|
-
# substitution. Ubuntu uses this extensively.
|
204
|
-
filename.gsub!(/\$\{(.+?)\}/) do |varname|
|
205
|
-
if value = httpd_infer_envvar($1, options)
|
206
|
-
log "Substituted \"#{varname}\" -> \"#{value}\""
|
207
|
-
value
|
208
|
-
else
|
209
|
-
log "Cannot substituted \"#{varname}\""
|
210
|
-
varname
|
211
|
-
end
|
212
|
-
end
|
213
|
-
if filename.include?("${")
|
214
|
-
# We couldn't substitute everything.
|
215
|
-
return nil
|
216
|
-
end
|
217
|
-
if filename !~ /\A\//
|
248
|
+
if contents =~ /^[ \t]*ErrorLog[ \t]+(.+)[ \t]*$/i
|
249
|
+
filename = unescape_apache_config_value($1, options)
|
250
|
+
if filename && filename !~ /\A\//
|
218
251
|
# Not an absolute path. Infer from root.
|
219
|
-
if root =
|
252
|
+
if root = httpd_default_root(options)
|
220
253
|
return "#{root}/#{filename}"
|
221
254
|
else
|
222
255
|
return nil
|
@@ -224,13 +257,15 @@ module PlatformInfo
|
|
224
257
|
else
|
225
258
|
return filename
|
226
259
|
end
|
227
|
-
elsif contents =~ /ErrorLog/
|
260
|
+
elsif contents =~ /ErrorLog/i
|
228
261
|
# The user apparently has ErrorLog set somewhere but
|
229
262
|
# we can't parse it. The default error log location,
|
230
263
|
# as reported by `httpd -V`, may be wrong (it is on OS X).
|
231
264
|
# So to be safe, let's assume that we don't know.
|
265
|
+
log "Unable to parse ErrorLog directive in Apache configuration file"
|
232
266
|
return nil
|
233
267
|
else
|
268
|
+
log "No ErrorLog directive in Apache configuration file"
|
234
269
|
return httpd_default_error_log(options)
|
235
270
|
end
|
236
271
|
else
|
@@ -278,25 +313,67 @@ module PlatformInfo
|
|
278
313
|
end
|
279
314
|
end
|
280
315
|
|
281
|
-
#
|
282
|
-
|
316
|
+
# Returns the path to the Apache `mods-available` subdirectory,
|
317
|
+
# or nil if it's not supported by this Apache.
|
318
|
+
def self.httpd_mods_available_directory(options = nil)
|
283
319
|
config_file = httpd_default_config_file(options)
|
284
|
-
if config_file
|
285
|
-
|
286
|
-
|
287
|
-
|
320
|
+
return nil if !config_file
|
321
|
+
|
322
|
+
# mods-available is supposed to be a Debian extension that only works
|
323
|
+
# on the APT-installed Apache, so only return non-nil if we're
|
324
|
+
# working against the APT-installed Apache.
|
325
|
+
config_dir = File.dirname(config_file)
|
326
|
+
if config_dir == "/etc/httpd" || config_dir == "/etc/apache2"
|
327
|
+
if File.exist?("#{config_dir}/mods-available") &&
|
328
|
+
File.exist?("#{config_dir}/mods-enabled")
|
329
|
+
return "#{config_dir}/mods-available"
|
330
|
+
else
|
331
|
+
return nil
|
332
|
+
end
|
333
|
+
else
|
334
|
+
return nil
|
335
|
+
end
|
336
|
+
end
|
337
|
+
memoize :httpd_mods_available_directory
|
338
|
+
|
339
|
+
# Returns the path to the Apache `mods-enabled` subdirectory,
|
340
|
+
# or nil if it's not supported by this Apache.
|
341
|
+
def self.httpd_mods_enabled_directory(options = nil)
|
342
|
+
config_file = httpd_default_config_file(options)
|
343
|
+
return nil if !config_file
|
344
|
+
|
345
|
+
# mods-enabled is supposed to be a Debian extension that only works
|
346
|
+
# on the APT-installed Apache, so only return non-nil if we're
|
347
|
+
# working against the APT-installed Apache.
|
348
|
+
config_dir = File.dirname(config_file)
|
349
|
+
if config_dir == "/etc/httpd" || config_dir == "/etc/apache2"
|
350
|
+
if File.exist?("#{config_dir}/mods-available") &&
|
351
|
+
File.exist?("#{config_dir}/mods-enabled")
|
352
|
+
return "#{config_dir}/mods-enabled"
|
353
|
+
else
|
354
|
+
return nil
|
355
|
+
end
|
288
356
|
else
|
289
357
|
return nil
|
290
358
|
end
|
291
359
|
end
|
360
|
+
memoize :httpd_mods_enabled_directory
|
292
361
|
|
293
362
|
# The absolute path to the 'a2enmod' executable.
|
294
363
|
def self.a2enmod(options = {})
|
295
364
|
apxs2 = options[:apxs2] || self.apxs2
|
296
|
-
|
297
|
-
|
365
|
+
dir = File.dirname(apxs2)
|
366
|
+
# a2enmod is supposed to be a Debian extension that only works
|
367
|
+
# on the APT-installed Apache, so only return non-nil if we're
|
368
|
+
# working against the APT-installed Apache.
|
369
|
+
if dir == "/usr/bin" || dir == "/usr/sbin"
|
370
|
+
if env_defined?('A2ENMOD')
|
371
|
+
return ENV['A2ENMOD']
|
372
|
+
else
|
373
|
+
return find_apache2_executable("a2enmod", options)
|
374
|
+
end
|
298
375
|
else
|
299
|
-
return
|
376
|
+
return nil
|
300
377
|
end
|
301
378
|
end
|
302
379
|
memoize :a2enmod
|
@@ -304,10 +381,16 @@ module PlatformInfo
|
|
304
381
|
# The absolute path to the 'a2enmod' executable.
|
305
382
|
def self.a2dismod(options = {})
|
306
383
|
apxs2 = options[:apxs2] || self.apxs2
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
384
|
+
dir = File.dirname(apxs2)
|
385
|
+
# a2dismod is supposed to be a Debian extension that only works
|
386
|
+
# on the APT-installed Apache, so only return non-nil if we're
|
387
|
+
# working against the APT-installed Apache.
|
388
|
+
if dir == "/usr/bin" || dir == "/usr/sbin"
|
389
|
+
if env_defined?('A2DISMOD')
|
390
|
+
return ENV['A2DISMOD']
|
391
|
+
else
|
392
|
+
return find_apache2_executable("a2dismod", options)
|
393
|
+
end
|
311
394
|
end
|
312
395
|
end
|
313
396
|
memoize :a2dismod
|
@@ -590,25 +673,111 @@ private
|
|
590
673
|
memoize :determine_apu_info, true
|
591
674
|
private_class_method :determine_apu_info
|
592
675
|
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
676
|
+
def self.scan_for_included_apache2_config_files(config_file, state, options = nil)
|
677
|
+
begin
|
678
|
+
config = File.open(config_file, "rb") do |f|
|
679
|
+
f.read
|
680
|
+
end
|
681
|
+
rescue Errno::EACCES
|
682
|
+
state[:unreadable_files] << config_file
|
683
|
+
return
|
601
684
|
end
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
685
|
+
|
686
|
+
found_filenames = []
|
687
|
+
|
688
|
+
config.scan(/^[ \t]*(Include(Optional)?|ServerRoot)[ \t]+(.+?)[ \t]*$/i) do |match|
|
689
|
+
if match[0].downcase == "serverroot"
|
690
|
+
new_root = unescape_apache_config_value(match[2], options)
|
691
|
+
state[:root] = new_root if new_root
|
692
|
+
else
|
693
|
+
filename = unescape_apache_config_value(match[2], options)
|
694
|
+
next if filename.nil? || filename.empty?
|
695
|
+
if filename !~ /\A\//
|
696
|
+
# Not an absolute path. Infer from root.
|
697
|
+
filename = "#{state[:root]}/#{filename}"
|
698
|
+
end
|
699
|
+
expand_apache2_glob(filename).each do |filename2|
|
700
|
+
if !state[:files].has_key?(filename2)
|
701
|
+
state[:files][filename2] = true
|
702
|
+
scan_for_included_apache2_config_files(filename2, state, options)
|
703
|
+
end
|
704
|
+
end
|
606
705
|
end
|
607
|
-
|
706
|
+
end
|
707
|
+
end
|
708
|
+
private_class_method :scan_for_included_apache2_config_files
|
709
|
+
|
710
|
+
def self.expand_apache2_glob(glob)
|
711
|
+
if File.directory?(glob)
|
712
|
+
glob = glob.sub(/\/*$/, '')
|
713
|
+
result = Dir["#{glob}/**/*"]
|
608
714
|
else
|
715
|
+
result = []
|
716
|
+
Dir[glob].each do |filename|
|
717
|
+
if File.directory?(filename)
|
718
|
+
result.concat(Dir["#{filename}/**/*"])
|
719
|
+
else
|
720
|
+
result << filename
|
721
|
+
end
|
722
|
+
end
|
723
|
+
end
|
724
|
+
result.reject! do |filename|
|
725
|
+
File.directory?(filename)
|
726
|
+
end
|
727
|
+
return result
|
728
|
+
end
|
729
|
+
private_class_method :expand_apache2_glob
|
730
|
+
|
731
|
+
def self.unescape_apache_config_value(value, options = nil)
|
732
|
+
if value =~ /^"(.*)"$/
|
733
|
+
value = unescape_c_string($1)
|
734
|
+
end
|
735
|
+
if value.include?("${")
|
736
|
+
log "Attempting to substitute environment variables in Apache config value #{value.inspect}..."
|
737
|
+
end
|
738
|
+
# The Apache config file supports environment variable
|
739
|
+
# substitution. Ubuntu uses this extensively.
|
740
|
+
value.gsub!(/\$\{(.+?)\}/) do |varname|
|
741
|
+
if substitution = httpd_infer_envvar($1, options)
|
742
|
+
log "Substituted \"#{varname}\" -> \"#{substitution}\""
|
743
|
+
substitution
|
744
|
+
else
|
745
|
+
log "Cannot substitute \"#{varname}\""
|
746
|
+
varname
|
747
|
+
end
|
748
|
+
end
|
749
|
+
if value.include?("${")
|
750
|
+
# We couldn't substitute everything.
|
609
751
|
return nil
|
752
|
+
else
|
753
|
+
return value
|
754
|
+
end
|
755
|
+
end
|
756
|
+
private_class_method :unescape_apache_config_value
|
757
|
+
|
758
|
+
def self.unescape_c_string(s)
|
759
|
+
state = 0
|
760
|
+
res = ''
|
761
|
+
backslash = "\\"
|
762
|
+
s.each_char do |c|
|
763
|
+
case state
|
764
|
+
when 0
|
765
|
+
case c
|
766
|
+
when backslash then state = 1
|
767
|
+
else res << c
|
768
|
+
end
|
769
|
+
when 1
|
770
|
+
case c
|
771
|
+
when 'n' then res << "\n"; state = 0
|
772
|
+
when 't' then res << "\t"; state = 0
|
773
|
+
when backslash then res << backslash; state = 0
|
774
|
+
else res << backslash; res << c; state = 0
|
775
|
+
end
|
776
|
+
end
|
610
777
|
end
|
778
|
+
return res
|
611
779
|
end
|
780
|
+
private_class_method :unescape_c_string
|
612
781
|
end
|
613
782
|
|
614
783
|
end
|