passenger 5.0.16 → 5.0.17
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/CHANGELOG +10 -0
- data/build/cxx_tests.rb +3 -0
- data/ext/common/Constants.h +1 -1
- data/ext/common/MemoryKit/palloc.cpp +28 -3
- data/ext/common/MemoryKit/palloc.h +6 -0
- data/ext/common/agent/Watchdog/AgentWatcher.cpp +12 -8
- data/helper-scripts/prespawn +22 -7
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/standalone/start_command.rb +15 -14
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +10 -2
- data/lib/phusion_passenger/standalone/start_command/nginx_engine.rb +4 -4
- data/lib/phusion_passenger/utils.rb +18 -2
- data/resources/templates/standalone/config.erb +1 -1
- metadata +3 -2
- metadata.gz.asc +7 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzJjYjMxNmJjNzhhMGY5MDI4YzFkODExOTJkMGYxYmRmMTM5ZjA3OA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzVmNTBhOWE3NjhkYTYwNGZiZmVkMWU5YzhmYjZkYjU2YjM3YzRlOA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NjNlNGI1YmI1ZjMzMGVmOTRkMjRlMzY0ZTU1MmFlMTk2MjliZDJjMzVlMTg0
|
10
|
+
NjI3NmYxZTdlNTkxNGNiOTc5NmRjZmJjYzg4MTdhZjE3YTMxZmJkYWQzNDU3
|
11
|
+
NThjYzBlYTkxMWI4NWNmNzVhOWIwYjg1OGJlMzM1ZTU0NDYzMDM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDhiNGZiZWI1OGI4ZTkzZGVjNzBkYzgxYzEwYTFmZDA4MzA0YTZiNjk3MTZk
|
14
|
+
YjhhYWNhMmExNDVkZWQ2Y2NlYTE5MTRhZjIzZmU1MmVkNTY4ZjdkNmYzYjk3
|
15
|
+
OGMyMzM5Mzg0M2JiMDZiOWE2MGMwZjI2MGVlNTRhNTE3NjcxMWI=
|
checksums.yaml.gz.asc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
5
|
+
iQEcBAABAgAGBQJV7ioZAAoJECrHRaUKISqMzGMH/2hOLPNIte03VdFX8eYr6YhE
|
6
|
+
OPz0UoX3GOnqd+cUdGHS/+Z54LN2r7GYGKu4jdMY/8OjOhTX3iylPlK0VtsPfKoR
|
7
|
+
ne6IPl2S2msbwwATiveOl0v6fIOf/sg/ZO3uKpnuKN03AKB1ny8KAcw8WIlCFNff
|
8
|
+
GTwUCY72eBo5GUgnl/CzCn589OTDtMsxckTM3x7OeJ1j8eSNYw1sRCtkeQmcR3Lv
|
9
|
+
XX+vFGs3PV4+qry1ALwg3MjjX4jCtEMjOa8fvaTEqLLtPTwxYETXY2aVQraPVuM6
|
10
|
+
I6/aDBOFqtBp/Lz3vpJ3+m3xSSHaNWM1PqxOm3ZiG4LbnJdjTUP+4wCy/g5KCKE=
|
11
|
+
=FEca
|
12
12
|
-----END PGP SIGNATURE-----
|
data.tar.gz.asc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
5
|
+
iQEcBAABAgAGBQJV7ioYAAoJECrHRaUKISqMfqUH/jjqWUz7G3w7odcWAPmc1awo
|
6
|
+
XvOhFpJqTvwV6d1Cyr1gum7W3/LJ5qvfARGuZ6FcH11/rECTeg93wQmx8yHMwmTS
|
7
|
+
TKEhFQPPpMWt192t2qcHlJ1ybmkNP9e/47A9ca8H/Gq+xCJmHUa9Im3dd5mqcT3L
|
8
|
+
OmwnngZ7hv9xJ2fmtVgVAWL9LN7v5aIYJ9EcTmnQxQO7GCrqqGl72DPAxByfGItA
|
9
|
+
OfjEZZdHd5uyrMVN0/I9XPsIFhH6Zx1iTDhuYnxETiNlqQS/EX0yhmrO5FeZiC7Z
|
10
|
+
gvN33l70BDHEXPnDA6nP6pk2JdMXn2vBs7l3JtOLCO7mGKpiVrGpEZSspFe4YLI=
|
11
|
+
=sW38
|
12
12
|
-----END PGP SIGNATURE-----
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
Release 5.0.17
|
2
|
+
--------------
|
3
|
+
|
4
|
+
* Adds packages for Ubuntu 15.10 "Wily", even though Ubuntu 15.10 hasn't been released yet.
|
5
|
+
* Fixes some memory corruption issues in the palloc subsystem. Closes GH-1587.
|
6
|
+
* Fixes the Node.js `PhusionPassenger.on('exit')` event. This event worked if you restart the app or detach an application process, but not if you stop Passenger.
|
7
|
+
* Fixes support for `passenger_pre_start` URLs that contain very long authentication strings. This was caused by the fact that our Base64 encoder generated unexpected newlines.
|
8
|
+
* [Standalone] Improves application prestarting. Application prestarting is now available in combination with the 'builtin' engine, and now works when SSL is used.
|
9
|
+
|
10
|
+
|
1
11
|
Release 5.0.16
|
2
12
|
--------------
|
3
13
|
|
data/build/cxx_tests.rb
CHANGED
@@ -101,6 +101,9 @@ TEST_CXX_OBJECTS = {
|
|
101
101
|
'test/cxx/MemoryKit/MbufTest.o' => %w(
|
102
102
|
test/cxx/MemoryKit/MbufTest.cpp
|
103
103
|
ext/common/MemoryKit/mbuf.h),
|
104
|
+
'test/cxx/MemoryKit/PallocTest.o' => %w(
|
105
|
+
test/cxx/MemoryKit/PallocTest.cpp
|
106
|
+
ext/common/MemoryKit/mbuf.h),
|
104
107
|
'test/cxx/ServerKit/ChannelTest.o' => %w(
|
105
108
|
test/cxx/ServerKit/ChannelTest.cpp
|
106
109
|
ext/common/ServerKit/Channel.h
|
data/ext/common/Constants.h
CHANGED
@@ -107,8 +107,11 @@ psg_deinit_pool(psg_pool_t *pool)
|
|
107
107
|
}
|
108
108
|
}
|
109
109
|
|
110
|
-
|
110
|
+
p = pool->data.next;
|
111
|
+
while (p != NULL) {
|
112
|
+
psg_pool_t *next = p->data.next;
|
111
113
|
free(p);
|
114
|
+
p = next;
|
112
115
|
}
|
113
116
|
}
|
114
117
|
|
@@ -131,7 +134,16 @@ psg_reset_pool(psg_pool_t *pool, size_t size)
|
|
131
134
|
} else {
|
132
135
|
pool->large = NULL;
|
133
136
|
for (p = pool; p; p = p->data.next) {
|
134
|
-
|
137
|
+
char *m = (char *) p;
|
138
|
+
if (p == pool) {
|
139
|
+
m += sizeof(psg_pool_t);
|
140
|
+
} else {
|
141
|
+
m += sizeof(psg_pool_data_t);
|
142
|
+
}
|
143
|
+
m = psg_align_ptr(m, PSG_ALIGNMENT);
|
144
|
+
p->data.last = m;
|
145
|
+
|
146
|
+
p->data.failed = 0;
|
135
147
|
}
|
136
148
|
return false;
|
137
149
|
}
|
@@ -212,6 +224,10 @@ psg_palloc_block(psg_pool_t *pool, size_t size)
|
|
212
224
|
new_p->data.next = NULL;
|
213
225
|
new_p->data.failed = 0;
|
214
226
|
|
227
|
+
// We increment by sizeof(psg_pool_data_t) here, NOT
|
228
|
+
// sizeof(psg_pool_t). This is because all fields after `data`
|
229
|
+
// are only used in the first psg_pool_s object, not in any
|
230
|
+
// subsequently linked ones.
|
215
231
|
m += sizeof(psg_pool_data_t);
|
216
232
|
m = psg_align_ptr(m, PSG_ALIGNMENT);
|
217
233
|
new_p->data.last = m + size;
|
@@ -309,13 +325,22 @@ psg_pstrdup(psg_pool_t *pool, const Passenger::StaticString &str)
|
|
309
325
|
bool
|
310
326
|
psg_pfree(psg_pool_t *pool, void *p)
|
311
327
|
{
|
312
|
-
psg_pool_large_t *l;
|
328
|
+
psg_pool_large_t *l, *prev;
|
329
|
+
|
330
|
+
prev = NULL;
|
313
331
|
|
314
332
|
for (l = pool->large; l; l = l->next) {
|
315
333
|
if (p == l->alloc) {
|
316
334
|
free(l->alloc);
|
317
335
|
l->alloc = NULL;
|
336
|
+
if (prev != NULL) {
|
337
|
+
prev->next = l->next;
|
338
|
+
} else {
|
339
|
+
pool->large = l->next;
|
340
|
+
}
|
318
341
|
return true;
|
342
|
+
} else {
|
343
|
+
prev = l;
|
319
344
|
}
|
320
345
|
}
|
321
346
|
|
@@ -85,6 +85,12 @@ typedef struct {
|
|
85
85
|
|
86
86
|
struct psg_pool_s {
|
87
87
|
psg_pool_data_t data;
|
88
|
+
|
89
|
+
/*
|
90
|
+
* The following fields are only used for the first psg_pool_s,
|
91
|
+
* not for any subsequent psg_pool_s objects linked through
|
92
|
+
* `data.next`.
|
93
|
+
*/
|
88
94
|
size_t max;
|
89
95
|
psg_pool_t *current;
|
90
96
|
psg_pool_large_t *large;
|
@@ -172,21 +172,21 @@ protected:
|
|
172
172
|
*/
|
173
173
|
virtual bool processStartupInfo(pid_t pid, FileDescriptor &fd, const vector<string> &args) = 0;
|
174
174
|
|
175
|
+
/**
|
176
|
+
* Kill a process (but not its children) with SIGTERM.
|
177
|
+
* Does not wait until it has quit.
|
178
|
+
*/
|
175
179
|
static void killAndDontWait(pid_t pid) {
|
176
180
|
this_thread::disable_interruption di;
|
177
181
|
this_thread::disable_syscall_interruption dsi;
|
178
|
-
|
179
|
-
// group will likely kill all its child processes too.
|
180
|
-
if (syscalls::killpg(pid, SIGTERM) == -1) {
|
181
|
-
syscalls::kill(pid, SIGTERM);
|
182
|
-
}
|
182
|
+
syscalls::kill(pid, SIGTERM);
|
183
183
|
}
|
184
184
|
|
185
185
|
/**
|
186
186
|
* Kill a process with SIGKILL, and attempt to kill its children too.
|
187
187
|
* Then wait until it has quit.
|
188
188
|
*/
|
189
|
-
static void
|
189
|
+
static void killProcessGroupAndWait(pid_t pid) {
|
190
190
|
this_thread::disable_interruption di;
|
191
191
|
this_thread::disable_syscall_interruption dsi;
|
192
192
|
// If the process is a process group leader then killing the
|
@@ -340,7 +340,7 @@ public:
|
|
340
340
|
fds[1].close();
|
341
341
|
this_thread::restore_interruption ri(di);
|
342
342
|
this_thread::restore_syscall_interruption rsi(dsi);
|
343
|
-
ScopeGuard failGuard(boost::bind(
|
343
|
+
ScopeGuard failGuard(boost::bind(killProcessGroupAndWait, pid));
|
344
344
|
|
345
345
|
/* Send startup arguments. Ignore EPIPE and ECONNRESET here
|
346
346
|
* because the child process might have sent an feedback message
|
@@ -477,6 +477,10 @@ public:
|
|
477
477
|
}
|
478
478
|
}
|
479
479
|
|
480
|
+
/**
|
481
|
+
* Tell the agent process to gracefully shut down. Returns true if it
|
482
|
+
* was signaled, or false if it wasn't started.
|
483
|
+
*/
|
480
484
|
virtual bool signalShutdown() {
|
481
485
|
boost::lock_guard<boost::mutex> l(lock);
|
482
486
|
if (pid == 0) {
|
@@ -496,7 +500,7 @@ public:
|
|
496
500
|
if (pid == 0) {
|
497
501
|
return false;
|
498
502
|
} else {
|
499
|
-
|
503
|
+
killProcessGroupAndWait(pid);
|
500
504
|
this->pid = 0;
|
501
505
|
return true;
|
502
506
|
}
|
data/helper-scripts/prespawn
CHANGED
@@ -48,14 +48,14 @@ class PrespawnLocation
|
|
48
48
|
def self.parse(url)
|
49
49
|
uri = uri_for(url)
|
50
50
|
|
51
|
-
|
52
|
-
UNIXPrespawnLocation.new(uri)
|
51
|
+
if uri.scheme == 'unix' || uri.host == 'unix'
|
52
|
+
location = UNIXPrespawnLocation.new(uri)
|
53
53
|
else
|
54
54
|
case uri.scheme
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
when 'http'
|
56
|
+
location = TCPPrespawnLocation.new(uri)
|
57
|
+
when 'https'
|
58
|
+
location = SSLPrespawnLocation.new(uri)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -88,10 +88,25 @@ class PrespawnLocation
|
|
88
88
|
@socket ||= connect
|
89
89
|
end
|
90
90
|
|
91
|
+
if Base64.respond_to?(:strict_encode64)
|
92
|
+
def base64(data)
|
93
|
+
Base64.strict_encode64(data)
|
94
|
+
end
|
95
|
+
else
|
96
|
+
# Base64-encodes the given data. Newlines are removed.
|
97
|
+
# This is like `Base64.strict_encode64`, but also works
|
98
|
+
# on Ruby 1.8 which doesn't have that method.
|
99
|
+
def base64(data)
|
100
|
+
result = Base64.encode64(data)
|
101
|
+
result.delete!("\n")
|
102
|
+
result
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
91
106
|
def head_request
|
92
107
|
socket.write("HEAD #{request_path} HTTP/1.1\r\n")
|
93
108
|
socket.write("Host: #{request_host}\r\n")
|
94
|
-
socket.write("Authorization: Basic " +
|
109
|
+
socket.write("Authorization: Basic " + base64(@uri.userinfo) + "\r\n") if @uri.userinfo
|
95
110
|
socket.write("Connection: close\r\n")
|
96
111
|
socket.write("\r\n")
|
97
112
|
|
data/lib/phusion_passenger.rb
CHANGED
@@ -30,7 +30,7 @@ module PhusionPassenger
|
|
30
30
|
|
31
31
|
PACKAGE_NAME = 'passenger'
|
32
32
|
# Run 'rake ext/common/Constants.h' after changing this number.
|
33
|
-
VERSION_STRING = '5.0.
|
33
|
+
VERSION_STRING = '5.0.17'
|
34
34
|
|
35
35
|
PREFERRED_NGINX_VERSION = '1.8.0'
|
36
36
|
NGINX_SHA256_CHECKSUM = '23cca1239990c818d8f6da118320c4979aadf5386deda691b1b7c2c96b9df3d5'
|
@@ -452,8 +452,8 @@ module PhusionPassenger
|
|
452
452
|
end
|
453
453
|
|
454
454
|
if @options[:engine] == "builtin"
|
455
|
-
# We explicitly check
|
456
|
-
# in case they
|
455
|
+
# We explicitly check that some options are set and warn the user about this,
|
456
|
+
# in case they are using the builtin engine. We don't warn about options
|
457
457
|
# that begin with --nginx- because that should be obvious.
|
458
458
|
check_nginx_option_used_with_builtin_engine(:ssl, "--ssl")
|
459
459
|
check_nginx_option_used_with_builtin_engine(:ssl_certificate, "--ssl-certificate")
|
@@ -609,33 +609,34 @@ module PhusionPassenger
|
|
609
609
|
start_engine_real
|
610
610
|
end
|
611
611
|
|
612
|
-
# Returns the URL that the server will be listening on
|
613
|
-
|
614
|
-
|
615
|
-
|
612
|
+
# Returns the URL that the server will be listening on
|
613
|
+
# for the given app.
|
614
|
+
def listen_url(app)
|
615
|
+
if app[:socket_file]
|
616
|
+
"unix:#{app[:socket_file]}"
|
616
617
|
else
|
617
|
-
if @options[:ssl] &&
|
618
|
+
if @options[:engine] == 'nginx' && app[:ssl] && !app[:ssl_port]
|
618
619
|
scheme = "https"
|
619
620
|
else
|
620
621
|
scheme = "http"
|
621
622
|
end
|
622
623
|
result = "#{scheme}://"
|
623
|
-
if
|
624
|
-
result <<
|
624
|
+
if app[:port] == 80
|
625
|
+
result << app[:address]
|
625
626
|
else
|
626
|
-
result << compose_ip_and_port(
|
627
|
+
result << compose_ip_and_port(app[:address], app[:port])
|
627
628
|
end
|
628
629
|
result << "/"
|
629
|
-
|
630
|
+
result
|
630
631
|
end
|
631
632
|
end
|
632
633
|
|
633
634
|
def compose_ip_and_port(ip, port)
|
634
635
|
if ip =~ /:/
|
635
636
|
# IPv6
|
636
|
-
|
637
|
+
"[#{ip}]:#{port}"
|
637
638
|
else
|
638
|
-
|
639
|
+
"#{ip}:#{port}"
|
639
640
|
end
|
640
641
|
end
|
641
642
|
|
@@ -644,7 +645,7 @@ module PhusionPassenger
|
|
644
645
|
puts "PID file: #{@options[:pid_file]}"
|
645
646
|
puts "Log file: #{@options[:log_file]}"
|
646
647
|
puts "Environment: #{@options[:environment]}"
|
647
|
-
puts "Accessible via: #{listen_url}"
|
648
|
+
puts "Accessible via: #{listen_url(@apps[0])}"
|
648
649
|
|
649
650
|
puts
|
650
651
|
if @options[:daemonize]
|
@@ -25,6 +25,7 @@
|
|
25
25
|
require 'etc'
|
26
26
|
PhusionPassenger.require_passenger_lib 'constants'
|
27
27
|
PhusionPassenger.require_passenger_lib 'standalone/control_utils'
|
28
|
+
PhusionPassenger.require_passenger_lib 'utils'
|
28
29
|
PhusionPassenger.require_passenger_lib 'utils/shellwords'
|
29
30
|
PhusionPassenger.require_passenger_lib 'utils/json'
|
30
31
|
|
@@ -89,6 +90,7 @@ module PhusionPassenger
|
|
89
90
|
command << " --no-delete-pid-file"
|
90
91
|
command << " --cleanup-pidfile #{Shellwords.escape @working_dir}/temp_dir_toucher.pid"
|
91
92
|
command << " --report-file #{Shellwords.escape @working_dir}/report.json"
|
93
|
+
command << " --ctl prestart_urls=#{Shellwords.escape prestart_urls_base64}"
|
92
94
|
add_param(command, :user, "--user")
|
93
95
|
add_param(command, :log_file, "--log-file")
|
94
96
|
add_param(command, :pid_file, "--pid-file")
|
@@ -114,7 +116,9 @@ module PhusionPassenger
|
|
114
116
|
end
|
115
117
|
|
116
118
|
command << " --BC"
|
117
|
-
|
119
|
+
# The builtin engine cannot be used in combination with Mass Deployment,
|
120
|
+
# so we know @apps always has 1 app.
|
121
|
+
command << " --listen #{listen_address(@apps[0])}"
|
118
122
|
command << " --no-graceful-exit"
|
119
123
|
add_param(command, :environment, "--environment")
|
120
124
|
add_param(command, :app_type, "--app-type")
|
@@ -167,12 +171,16 @@ module PhusionPassenger
|
|
167
171
|
|
168
172
|
def listen_address(options = @options, for_ping_port = false)
|
169
173
|
if options[:socket_file]
|
170
|
-
return "unix
|
174
|
+
return "unix:#{options[:socket_file]}"
|
171
175
|
else
|
172
176
|
return "tcp://" + compose_ip_and_port(options[:address], options[:port])
|
173
177
|
end
|
174
178
|
end
|
175
179
|
|
180
|
+
def prestart_urls_base64
|
181
|
+
Utils.base64(listen_url(@apps[0]))
|
182
|
+
end
|
183
|
+
|
176
184
|
def add_param(command, option_name, param_name)
|
177
185
|
if value = @options[option_name]
|
178
186
|
command << " #{param_name} #{Shellwords.escape value.to_s}"
|
@@ -140,17 +140,17 @@ module PhusionPassenger
|
|
140
140
|
|
141
141
|
def nginx_listen_address(options = @options)
|
142
142
|
if options[:socket_file]
|
143
|
-
|
143
|
+
"unix:#{options[:socket_file]}"
|
144
144
|
else
|
145
|
-
|
145
|
+
compose_ip_and_port(options[:address], options[:port])
|
146
146
|
end
|
147
147
|
end
|
148
148
|
|
149
149
|
def nginx_listen_address_with_ssl_port(options = @options)
|
150
150
|
if options[:socket_file]
|
151
|
-
|
151
|
+
"unix:#{options[:socket_file]}"
|
152
152
|
else
|
153
|
-
|
153
|
+
compose_ip_and_port(options[:address], options[:ssl_port])
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
@@ -22,6 +22,8 @@
|
|
22
22
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
23
|
# THE SOFTWARE.
|
24
24
|
|
25
|
+
require 'base64'
|
26
|
+
|
25
27
|
module PhusionPassenger
|
26
28
|
|
27
29
|
# Utility functions.
|
@@ -44,8 +46,7 @@ module PhusionPassenger
|
|
44
46
|
end
|
45
47
|
case method
|
46
48
|
when :base64
|
47
|
-
data =
|
48
|
-
data.gsub!("\n", '')
|
49
|
+
data = base64(data)
|
49
50
|
data.gsub!("+", '')
|
50
51
|
data.gsub!("/", '')
|
51
52
|
data.gsub!(/==$/, '')
|
@@ -179,6 +180,21 @@ module PhusionPassenger
|
|
179
180
|
end
|
180
181
|
end
|
181
182
|
|
183
|
+
if Base64.respond_to?(:strict_encode64)
|
184
|
+
def base64(data)
|
185
|
+
Base64.strict_encode64(data)
|
186
|
+
end
|
187
|
+
else
|
188
|
+
# Base64-encodes the given data. Newlines are removed.
|
189
|
+
# This is like `Base64.strict_encode64`, but also works
|
190
|
+
# on Ruby 1.8 which doesn't have that method.
|
191
|
+
def base64(data)
|
192
|
+
result = Base64.encode64(data)
|
193
|
+
result.delete!("\n")
|
194
|
+
result
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
182
198
|
# Returns a string which reports the backtraces for all threads,
|
183
199
|
# or if that's not supported the backtrace for the current thread.
|
184
200
|
def global_backtrace_report
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passenger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phusion - http://www.phusion.nl/
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08
|
11
|
+
date: 2015-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -3002,3 +3002,4 @@ specification_version: 4
|
|
3002
3002
|
summary: A fast and robust web server and application server for Ruby, Python and
|
3003
3003
|
Node.js
|
3004
3004
|
test_files: []
|
3005
|
+
has_rdoc:
|
metadata.gz.asc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
5
|
+
iQEcBAABAgAGBQJV7ioYAAoJECrHRaUKISqMiEgH/0j/WQ+R1IvFOWDI7X8m8Wa0
|
6
|
+
cBKEsW/zNGGLLC1zi86EM3r6BZIjmhaADvuq0CPALsVkBdNpKycxxLOe4quA9Brm
|
7
|
+
a1QVgKmnhimThewopw0TGJTOiYmLdERR9NTeUpuRRkWytUKJem6MvDyNlW52bQwJ
|
8
|
+
88QMLHow5Uu8JZoWEfxhX9nizNgESNus+takRHE85WY6G6F2YGMGx3w3eBSX/M2i
|
9
|
+
3Ud6Z2D1X1AgdcsVvbHtsOoYap4+IsE/95Y6H3up9DakJN0PfPYn4hHAKoxzX1Ma
|
10
|
+
+yESKP1UrNBPqrwc5j2eHUaPnKP+hgjcc/QEmOQs7QzeXYneIcOSzPo8j38Zgto=
|
11
|
+
=7g/4
|
12
12
|
-----END PGP SIGNATURE-----
|