passenger 4.0.37 → 4.0.38
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/{NEWS → CHANGELOG} +45 -1
- data/build/misc.rb +5 -5
- data/debian.template/control.template +1 -1
- data/debian.template/passenger.docs +1 -1
- data/doc/users_guide_snippets/installation.txt +1 -1
- data/doc/users_guide_snippets/tips.txt +3 -2
- data/ext/apache2/Hooks.cpp +20 -3
- data/ext/common/AgentsStarter.h +10 -8
- data/ext/common/ApplicationPool2/Implementation.cpp +1 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/Exceptions.cpp +1 -1
- data/ext/common/ServerInstanceDir.h +22 -16
- data/ext/common/Utils.cpp +15 -37
- data/ext/common/Utils.h +0 -6
- data/ext/common/Utils/ProcessMetricsCollector.h +12 -6
- data/ext/nginx/ContentHandler.c +24 -3
- data/helper-scripts/meteor-loader.rb +1 -1
- data/helper-scripts/prespawn +2 -0
- data/helper-scripts/wsgi-loader.py +1 -1
- data/lib/phusion_passenger.rb +5 -5
- data/lib/phusion_passenger/abstract_installer.rb +1 -0
- data/lib/phusion_passenger/native_support.rb +63 -34
- data/lib/phusion_passenger/packaging.rb +1 -0
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +87 -17
- data/lib/phusion_passenger/standalone/start_command.rb +26 -7
- data/lib/phusion_passenger/utils/terminal_choice_menu.rb +3 -9
- data/lib/phusion_passenger/utils/tmpio.rb +15 -4
- data/passenger.gemspec +1 -1
- data/test/integration_tests/apache2_tests.rb +34 -0
- data/test/integration_tests/shared/example_webapp_tests.rb +47 -19
- metadata +5 -5
- metadata.gz.asc +7 -7
data/ext/common/Utils.h
CHANGED
@@ -65,8 +65,6 @@ typedef enum {
|
|
65
65
|
FT_REGULAR,
|
66
66
|
/** A directory. */
|
67
67
|
FT_DIRECTORY,
|
68
|
-
/** A symlink. Only returned by getFileTypeNoFollowSymlinks(), not by getFileType(). */
|
69
|
-
FT_SYMLINK,
|
70
68
|
/** Something else, e.g. a pipe or a socket. */
|
71
69
|
FT_OTHER
|
72
70
|
} FileType;
|
@@ -123,10 +121,6 @@ bool fileExists(const StaticString &filename, CachedFileStat *cstat = 0,
|
|
123
121
|
*/
|
124
122
|
FileType getFileType(const StaticString &filename, CachedFileStat *cstat = 0,
|
125
123
|
unsigned int throttleRate = 0);
|
126
|
-
/**
|
127
|
-
* Like getFileType(), but does not follow symlinks.
|
128
|
-
*/
|
129
|
-
FileType getFileTypeNoFollowSymlinks(const StaticString &filename);
|
130
124
|
|
131
125
|
/**
|
132
126
|
* Create the given file with the given contents, permissions and ownership.
|
@@ -450,14 +450,19 @@ public:
|
|
450
450
|
if (pidsArg[pidsArg.size() - 1] == ',') {
|
451
451
|
pidsArg.resize(pidsArg.size() - 1);
|
452
452
|
}
|
453
|
+
|
454
|
+
// The list of format arguments must also follow -o
|
455
|
+
// without a space.
|
456
|
+
// https://github.com/phusion/passenger/pull/94
|
457
|
+
string fmtArg = "-o";
|
458
|
+
#if defined(sun) || defined(__sun)
|
459
|
+
fmtArg.append("pid,ppid,pcpu,rss,vsz,pgid,uid,args");
|
460
|
+
#else
|
461
|
+
fmtArg.append("pid,ppid,%cpu,rss,vsize,pgid,uid,command");
|
462
|
+
#endif
|
453
463
|
|
454
464
|
const char *command[] = {
|
455
|
-
"ps",
|
456
|
-
#if defined(sun) || defined(__sun)
|
457
|
-
"pid,ppid,pcpu,rss,vsz,pgid,uid,args",
|
458
|
-
#else
|
459
|
-
"pid,ppid,%cpu,rss,vsize,pgid,uid,command",
|
460
|
-
#endif
|
465
|
+
"ps", fmtArg.c_str(),
|
461
466
|
#ifdef PS_SUPPORTS_MULTIPLE_PIDS
|
462
467
|
pidsArg.c_str(),
|
463
468
|
#endif
|
@@ -469,6 +474,7 @@ public:
|
|
469
474
|
psOutput = runCommandAndCaptureOutput(command);
|
470
475
|
}
|
471
476
|
pidsArg.resize(0);
|
477
|
+
fmtArg.resize(0);
|
472
478
|
ProcessMetricMap result = parsePsOutput<Collection, ConstIterator>(psOutput, pids);
|
473
479
|
psOutput.resize(0);
|
474
480
|
if (canMeasureRealMemory) {
|
data/ext/nginx/ContentHandler.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* Copyright (C) Igor Sysoev
|
3
3
|
* Copyright (C) 2007 Manlio Perillo (manlio.perillo@gmail.com)
|
4
|
-
* Copyright (C) 2010-
|
4
|
+
* Copyright (C) 2010-2014 Phusion
|
5
5
|
*
|
6
6
|
* Redistribution and use in source and binary forms, with or without
|
7
7
|
* modification, are permitted provided that the following conditions
|
@@ -305,6 +305,21 @@ create_key(ngx_http_request_t *r)
|
|
305
305
|
|
306
306
|
#endif
|
307
307
|
|
308
|
+
/**
|
309
|
+
* Checks whether the given header is "Transfer-Encoding".
|
310
|
+
* We do not pass Transfer-Encoding headers to the HelperAgent because
|
311
|
+
* Nginx always buffers the request body and always sets Content-Length
|
312
|
+
* in the request headers.
|
313
|
+
*/
|
314
|
+
static int
|
315
|
+
header_is_transfer_encoding(ngx_str_t *key)
|
316
|
+
{
|
317
|
+
return key->len == sizeof("transfer-encoding") - 1 &&
|
318
|
+
ngx_tolower(key->data[0]) == (u_char) 't' &&
|
319
|
+
ngx_tolower(key->data[sizeof("transfer-encoding") - 2]) == (u_char) 'g' &&
|
320
|
+
ngx_strncasecmp(key->data + 1, (u_char *) "ransfer-encodin", sizeof("ransfer-encodin") - 1) == 0;
|
321
|
+
}
|
322
|
+
|
308
323
|
|
309
324
|
static ngx_int_t
|
310
325
|
create_request(ngx_http_request_t *r)
|
@@ -475,8 +490,10 @@ create_request(ngx_http_request_t *r)
|
|
475
490
|
i = 0;
|
476
491
|
}
|
477
492
|
|
478
|
-
|
479
|
-
+ header[i].
|
493
|
+
if (!header_is_transfer_encoding(&header[i].key)) {
|
494
|
+
len += sizeof("HTTP_") - 1 + header[i].key.len + 1
|
495
|
+
+ header[i].value.len + 1;
|
496
|
+
}
|
480
497
|
}
|
481
498
|
}
|
482
499
|
|
@@ -656,6 +673,10 @@ create_request(ngx_http_request_t *r)
|
|
656
673
|
i = 0;
|
657
674
|
}
|
658
675
|
|
676
|
+
if (header_is_transfer_encoding(&header[i].key)) {
|
677
|
+
continue;
|
678
|
+
}
|
679
|
+
|
659
680
|
b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
|
660
681
|
|
661
682
|
for (n = 0; n < header[i].key.len; n++) {
|
@@ -107,7 +107,7 @@ module App
|
|
107
107
|
abort "Cannot find a suitable port to start Meteor on"
|
108
108
|
end
|
109
109
|
|
110
|
-
production = options["environment"] == "production" ? "production" : ""
|
110
|
+
production = options["environment"] == "production" ? "--production" : ""
|
111
111
|
pid = fork do
|
112
112
|
# Meteor is quite !@#$% here: if we kill its start script
|
113
113
|
# with *any* signal, it'll leave a ton of garbage processes
|
data/helper-scripts/prespawn
CHANGED
@@ -191,7 +191,7 @@ class RequestHandler:
|
|
191
191
|
env['wsgi.version'] = (1, 0)
|
192
192
|
env['wsgi.multithread'] = False
|
193
193
|
env['wsgi.multiprocess'] = True
|
194
|
-
env['wsgi.run_once'] =
|
194
|
+
env['wsgi.run_once'] = False
|
195
195
|
if env.get('HTTPS','off') in ('on', '1', 'true', 'yes'):
|
196
196
|
env['wsgi.url_scheme'] = 'https'
|
197
197
|
else:
|
data/lib/phusion_passenger.rb
CHANGED
@@ -30,13 +30,13 @@ module PhusionPassenger
|
|
30
30
|
|
31
31
|
PACKAGE_NAME = 'passenger'
|
32
32
|
# Run 'rake ext/common/Constants.h' after changing this number.
|
33
|
-
VERSION_STRING = '4.0.
|
33
|
+
VERSION_STRING = '4.0.38'
|
34
34
|
|
35
|
-
PREFERRED_NGINX_VERSION = '1.4.
|
36
|
-
NGINX_SHA256_CHECKSUM = '
|
35
|
+
PREFERRED_NGINX_VERSION = '1.4.6'
|
36
|
+
NGINX_SHA256_CHECKSUM = '7a8b5b15d708b5b9c61e723bd93faa247b06c8b90babb76f612c128edb5812c6'
|
37
37
|
|
38
|
-
PREFERRED_PCRE_VERSION = '8.
|
39
|
-
PCRE_SHA256_CHECKSUM = '
|
38
|
+
PREFERRED_PCRE_VERSION = '8.34'
|
39
|
+
PCRE_SHA256_CHECKSUM = '1dd78994c81e44ac41cf30b2a21d4b4cc6d76ccde7fc6e77713ed51d7bddca47'
|
40
40
|
|
41
41
|
STANDALONE_INTERFACE_VERSION = 1
|
42
42
|
|
@@ -213,7 +213,6 @@ private
|
|
213
213
|
|
214
214
|
STDERR.puts " --> Compiling #{library_name} for the current Ruby interpreter..."
|
215
215
|
STDERR.puts " (set PASSENGER_COMPILE_NATIVE_SUPPORT_BINARY=0 to disable)"
|
216
|
-
STDERR.puts " -------------------------------"
|
217
216
|
|
218
217
|
require 'fileutils'
|
219
218
|
require 'shellwords'
|
@@ -268,9 +267,17 @@ private
|
|
268
267
|
return PhusionPassenger::Utils::Download.download(url, filename, real_options)
|
269
268
|
end
|
270
269
|
|
271
|
-
def
|
270
|
+
def log(message, options = {})
|
271
|
+
if logger = options[:logger]
|
272
|
+
logger.puts(message)
|
273
|
+
else
|
274
|
+
STDERR.puts " #{message}"
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def mkdir(dir, options = {})
|
272
279
|
begin
|
273
|
-
|
280
|
+
log("# mkdir -p #{dir}", options)
|
274
281
|
FileUtils.mkdir_p(dir)
|
275
282
|
rescue Errno::EEXIST
|
276
283
|
end
|
@@ -282,39 +289,57 @@ private
|
|
282
289
|
end
|
283
290
|
end
|
284
291
|
|
285
|
-
def sh_nonfatal(command_string)
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
+
def sh_nonfatal(command_string, options = {})
|
293
|
+
log("# #{command_string}", options)
|
294
|
+
if logger = options[:logger]
|
295
|
+
s_logpath = Shellwords.escape(logger.path)
|
296
|
+
return system("(#{command_string}) >>#{s_logpath} 2>&1")
|
297
|
+
else
|
298
|
+
Utils.mktmpdir("passenger-native-support-") do |tmpdir|
|
299
|
+
s_tmpdir = Shellwords.escape(tmpdir)
|
300
|
+
result = system("(#{command_string}) >#{s_tmpdir}/log 2>&1")
|
301
|
+
system("cat #{s_tmpdir}/log | sed 's/^/ /' >&2")
|
302
|
+
return result
|
303
|
+
end
|
292
304
|
end
|
293
305
|
end
|
294
306
|
|
295
307
|
def compile(target_dirs)
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
308
|
+
logger = Utils::TmpIO.new('passenger_native_support',
|
309
|
+
:mode => File::WRONLY | File::APPEND,
|
310
|
+
:binary => false,
|
311
|
+
:suffix => ".log",
|
312
|
+
:unlink_immediately => false)
|
313
|
+
options = { :logger => logger }
|
314
|
+
begin
|
315
|
+
try_directories(target_dirs, options) do |target_dir|
|
316
|
+
result =
|
317
|
+
sh_nonfatal("#{PlatformInfo.ruby_command} #{Shellwords.escape extconf_rb}",
|
318
|
+
options) &&
|
319
|
+
sh_nonfatal("make clean && make", options)
|
320
|
+
if result
|
321
|
+
log "Compilation succesful. The logs are here:"
|
322
|
+
log logger.path
|
323
|
+
[target_dir, false]
|
324
|
+
else
|
325
|
+
log "Warning: compilation didn't succeed. To learn why, read this file:"
|
326
|
+
log logger.path
|
327
|
+
[nil, false]
|
328
|
+
end
|
306
329
|
end
|
307
330
|
end
|
331
|
+
ensure
|
332
|
+
logger.close if logger
|
308
333
|
end
|
309
334
|
|
310
|
-
def try_directories(dirs)
|
335
|
+
def try_directories(dirs, options = {})
|
311
336
|
result = nil
|
312
337
|
dirs.each_with_index do |dir, i|
|
313
338
|
begin
|
314
|
-
mkdir(dir)
|
339
|
+
mkdir(dir, options)
|
315
340
|
File.open("#{dir}/.permission_test", "w").close
|
316
341
|
File.unlink("#{dir}/.permission_test")
|
317
|
-
|
342
|
+
log("# cd #{dir}", options)
|
318
343
|
Dir.chdir(dir) do
|
319
344
|
result, should_retry = yield(dir)
|
320
345
|
return result if !should_retry
|
@@ -325,26 +350,30 @@ private
|
|
325
350
|
# error on the last one too then propagate the
|
326
351
|
# exception.
|
327
352
|
if i == dirs.size - 1
|
328
|
-
|
329
|
-
"but no more directories to try. Giving up."
|
330
|
-
|
353
|
+
log("Encountered permission error, " +
|
354
|
+
"but no more directories to try. Giving up.",
|
355
|
+
options)
|
356
|
+
log("-------------------------------", options)
|
331
357
|
return nil
|
332
358
|
else
|
333
|
-
|
334
|
-
"trying a different directory..."
|
335
|
-
|
359
|
+
log("Encountered permission error, " +
|
360
|
+
"trying a different directory...",
|
361
|
+
options)
|
362
|
+
log("-------------------------------", options)
|
336
363
|
end
|
337
364
|
rescue Errno::ENOTDIR
|
338
365
|
# This can occur when locations.ini set buildout_dir
|
339
366
|
# to an invalid path. Just ignore this error.
|
340
367
|
if i == dirs.size - 1
|
341
|
-
|
342
|
-
"but no more directories to try. Giving up."
|
343
|
-
|
368
|
+
log("Not a valid directory, " +
|
369
|
+
"but no more directories to try. Giving up.",
|
370
|
+
options)
|
371
|
+
log("-------------------------------", options)
|
344
372
|
return nil
|
345
373
|
else
|
346
|
-
|
347
|
-
|
374
|
+
log("Not a valid directory. Trying a different one...",
|
375
|
+
options)
|
376
|
+
log("-------------------------------", options)
|
348
377
|
end
|
349
378
|
end
|
350
379
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: binary
|
2
2
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
# Copyright (c) 2012-
|
3
|
+
# Copyright (c) 2012-2014 Phusion
|
4
4
|
#
|
5
5
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
6
6
|
#
|
@@ -28,34 +28,104 @@ module PhusionPassenger
|
|
28
28
|
module Rack
|
29
29
|
|
30
30
|
class OutOfBandGc
|
31
|
-
|
31
|
+
# Usage:
|
32
|
+
#
|
33
|
+
# OutOfBandGc.new(app, frequency, logger = nil)
|
34
|
+
# OutOfBandGc.new(app, options = {})
|
35
|
+
def initialize(app, *args)
|
32
36
|
@app = app
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
disabled = GC.enable
|
40
|
-
GC.start
|
41
|
-
GC.disable if disabled
|
42
|
-
logger.info "Out Of Band GC finished in #{Time.now - t0} sec" if logger
|
37
|
+
if args.size == 0 || (args.size == 1 && args[0].is_a?(Hash))
|
38
|
+
# OutOfBandGc.new(app, options = {})
|
39
|
+
initialize_with_options(args[0] || {})
|
40
|
+
else
|
41
|
+
# OutOfBandGc.new(app, frequency, logger = nil)
|
42
|
+
initialize_legacy(*args)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
def call(env)
|
47
47
|
status, headers, body = @app.call(env)
|
48
48
|
|
49
|
-
@
|
50
|
-
|
51
|
-
|
52
|
-
@request_count
|
49
|
+
case @strategy
|
50
|
+
when :counting
|
51
|
+
@mutex.synchronize do
|
52
|
+
@request_count += 1
|
53
|
+
if @request_count == @frequency
|
54
|
+
@request_count = 0
|
55
|
+
headers['X-Passenger-Request-OOB-Work'] = 'true'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
when :gctools_oobgc
|
60
|
+
if GC::OOB.dry_run
|
53
61
|
headers['X-Passenger-Request-OOB-Work'] = 'true'
|
54
62
|
end
|
63
|
+
|
64
|
+
else
|
65
|
+
raise "Unrecognized Out-Of-Band GC strategy #{@strategy.inspect}"
|
55
66
|
end
|
56
|
-
|
67
|
+
|
57
68
|
[status, headers, body]
|
58
69
|
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def initialize_with_options(options)
|
73
|
+
@strategy = options[:strategy]
|
74
|
+
@logger = options[:logger]
|
75
|
+
|
76
|
+
case @strategy
|
77
|
+
when :counting
|
78
|
+
@frequency = options[:frequency]
|
79
|
+
@request_count = 0
|
80
|
+
@mutex = Mutex.new
|
81
|
+
if !@frequency || @frequency < 1
|
82
|
+
raise ArgumentError, "The :frequency option must be a number that is at least 1."
|
83
|
+
end
|
84
|
+
::PhusionPassenger.on_event(:oob_work) do
|
85
|
+
t0 = Time.now
|
86
|
+
disabled = GC.enable
|
87
|
+
GC.start
|
88
|
+
GC.disable if disabled
|
89
|
+
@logger.info "Out Of Band GC finished in #{Time.now - t0} sec" if @logger
|
90
|
+
end
|
91
|
+
|
92
|
+
when :gctools_oobgc
|
93
|
+
if !defined?(::GC::OOB)
|
94
|
+
raise "To use the :gctools_oobgc strategy, " +
|
95
|
+
"first add 'gem \"gctools\"' to your Gemfile, " +
|
96
|
+
"then call 'require \"gctools/oobgc\"' and 'GC::OOB.setup' " +
|
97
|
+
"before using the #{self.class.name} middleware."
|
98
|
+
elsif !::GC::OOB.respond_to?(:dry_run)
|
99
|
+
raise "To use the :gctools_oobgc strategy, you must use a sufficiently " +
|
100
|
+
"recent version of the gctools gem. Please see this pull request: " +
|
101
|
+
"https://github.com/tmm1/gctools/pull/5"
|
102
|
+
elsif PhusionPassenger::App.options["spawn_method"] =~ /smart/
|
103
|
+
# Using GC::OOB with 'smart' currently results in a segfault.
|
104
|
+
raise "The :gctools_oobgc strategy cannot be used with the '" +
|
105
|
+
PhusionPassenger::App.options["spawn_method"] + "' spawning method. " +
|
106
|
+
"Please use 'direct'."
|
107
|
+
end
|
108
|
+
|
109
|
+
::PhusionPassenger.on_event(:oob_work) do
|
110
|
+
t0 = Time.now
|
111
|
+
GC::OOB.run
|
112
|
+
@logger.info "Out Of Band GC finished in #{Time.now - t0} sec" if @logger
|
113
|
+
end
|
114
|
+
|
115
|
+
when nil
|
116
|
+
raise ArgumentError, "You must specify an Out-Of-Band GC strategy with the :strategy option."
|
117
|
+
|
118
|
+
else
|
119
|
+
raise ArgumentError, "Invalid Out-Of-Band GC strategy #{@strategy.inspect}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def initialize_legacy(frequency, logger = nil)
|
124
|
+
initialize_with_options(
|
125
|
+
:strategy => :counting,
|
126
|
+
:frequency => frequency,
|
127
|
+
:logger => logger)
|
128
|
+
end
|
59
129
|
end
|
60
130
|
|
61
131
|
end # module Rack
|