passenger 4.0.0.rc4 → 4.0.0.rc6
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.
- data.tar.gz.asc +12 -0
- data/.travis.yml +4 -4
- data/NEWS +46 -0
- data/bin/passenger-config +31 -1
- data/bin/passenger-install-apache2-module +1 -1
- data/bin/passenger-install-nginx-module +1 -0
- data/build/common_library.rb +4 -0
- data/build/cplusplus_support.rb +27 -6
- data/build/cxx_tests.rb +1 -1
- data/build/misc.rb +28 -6
- data/build/packaging.rb +72 -65
- data/build/test_basics.rb +1 -1
- data/dev/googlecode_upload.py +265 -0
- data/dev/run_travis.sh +9 -0
- data/doc/Users guide Apache.html +376 -193
- data/doc/Users guide Apache.idmap.txt +80 -62
- data/doc/Users guide Apache.txt +61 -35
- data/doc/Users guide Nginx.html +278 -83
- data/doc/Users guide Nginx.idmap.txt +26 -10
- data/doc/Users guide Nginx.txt +59 -31
- data/doc/Users guide Standalone.html +1 -1
- data/doc/users_guide_snippets/installation.txt +121 -11
- data/doc/users_guide_snippets/rvm_helper_tool.txt +56 -0
- data/ext/apache2/Bucket.cpp +1 -1
- data/ext/apache2/Configuration.cpp +7 -1
- data/ext/apache2/Configuration.hpp +4 -0
- data/ext/apache2/Hooks.cpp +2 -2
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +1 -1
- data/ext/common/AgentsStarter.hpp +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +4 -8
- data/ext/common/ApplicationPool2/Group.h +17 -11
- data/ext/common/ApplicationPool2/Implementation.cpp +39 -11
- data/ext/common/ApplicationPool2/Pool.h +23 -4
- data/ext/common/ApplicationPool2/Process.h +30 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +3 -1
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +4 -0
- data/ext/common/Utils.cpp +21 -3
- data/ext/common/Utils.h +8 -1
- data/ext/common/Utils/HttpHeaderBufferer.h +1 -1
- data/ext/common/Utils/IOUtils.cpp +5 -4
- data/ext/common/Utils/IOUtils.h +32 -14
- data/ext/common/Utils/MessagePassing.h +2 -2
- data/ext/common/Utils/ProcessMetricsCollector.h +47 -15
- data/ext/common/Utils/ScopeGuard.h +20 -3
- data/ext/common/Utils/StrIntUtils.h +14 -5
- data/ext/common/agents/Base.cpp +161 -50
- data/ext/common/agents/HelperAgent/AgentOptions.h +2 -2
- data/ext/common/agents/HelperAgent/Main.cpp +1 -0
- data/ext/common/agents/HelperAgent/RequestHandler.h +166 -52
- data/ext/common/agents/LoggingAgent/Main.cpp +1 -1
- data/ext/common/agents/Watchdog/Main.cpp +2 -2
- data/ext/nginx/Configuration.c +31 -4
- data/ext/nginx/Configuration.h +1 -0
- data/ext/nginx/ContentHandler.c +148 -34
- data/ext/nginx/ngx_http_passenger_module.c +4 -1
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/macros.hpp +30 -8
- data/lib/phusion_passenger.rb +2 -2
- data/lib/phusion_passenger/classic_rails/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/native_support.rb +19 -1
- data/lib/phusion_passenger/platform_info/compiler.rb +6 -0
- data/lib/phusion_passenger/platform_info/ruby.rb +54 -5
- data/lib/phusion_passenger/preloader_shared_helpers.rb +8 -1
- data/lib/phusion_passenger/rack/out_of_band_gc.rb +3 -1
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +32 -5
- data/lib/phusion_passenger/request_handler/thread_handler.rb +28 -8
- data/lib/phusion_passenger/ruby_core_enhancements.rb +9 -1
- data/lib/phusion_passenger/standalone/runtime_installer.rb +1 -0
- data/lib/phusion_passenger/utils/unseekable_socket.rb +50 -5
- data/passenger.gemspec +1 -1
- data/resources/templates/apache2/config_snippets.txt.erb +1 -1
- data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -9
- data/test/cxx/RequestHandlerTest.cpp +5 -5
- data/test/ruby/classic_rails/loader_spec.rb +1 -1
- data/test/ruby/classic_rails/preloader_spec.rb +1 -1
- data/test/ruby/request_handler_spec.rb +207 -1
- data/test/ruby/shared/loader_sharedspec.rb +1 -0
- data/test/ruby/spec_helper.rb +11 -1
- data/test/stub/apache2/httpd.conf.erb +1 -1
- metadata +5 -3
- metadata.gz.asc +12 -0
data/passenger.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.version = PhusionPassenger::VERSION_STRING
|
13
13
|
s.rubyforge_project = "passenger"
|
14
14
|
s.author = "Phusion - http://www.phusion.nl/"
|
15
|
-
s.email = "
|
15
|
+
s.email = "software-signing@phusion.nl"
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.add_dependency 'rake', '>= 0.8.1'
|
18
18
|
s.add_dependency 'daemon_controller', '>= 1.1.0'
|
@@ -4,7 +4,7 @@ Please edit your Apache configuration file, and add these lines:
|
|
4
4
|
|
5
5
|
<b>LoadModule passenger_module <%= @module_location %></b>
|
6
6
|
<b>PassengerRoot <%= @passenger_root %></b>
|
7
|
-
<b>
|
7
|
+
<b>PassengerDefaultRuby <%= @ruby %></b>
|
8
8
|
|
9
9
|
After you restart Apache, you are ready to deploy any number of Ruby on Rails
|
10
10
|
applications on Apache, without any further Ruby on Rails-specific
|
@@ -1116,18 +1116,13 @@ namespace tut {
|
|
1116
1116
|
TEST_METHOD(64) {
|
1117
1117
|
// Test process idle cleaning.
|
1118
1118
|
Options options = createOptions();
|
1119
|
-
retainSessions = true;
|
1120
1119
|
pool->setMaxIdleTime(50000);
|
1121
|
-
pool->
|
1122
|
-
pool->
|
1123
|
-
EVENTUALLY(2,
|
1124
|
-
result = number == 2;
|
1125
|
-
);
|
1120
|
+
SessionPtr session1 = pool->get(options, &ticket);
|
1121
|
+
SessionPtr session2 = pool->get(options, &ticket);
|
1126
1122
|
ensure_equals(pool->getProcessCount(), 2u);
|
1127
|
-
|
1128
|
-
currentSession.reset();
|
1129
|
-
sessions.pop_back();
|
1130
1123
|
|
1124
|
+
session2.reset();
|
1125
|
+
|
1131
1126
|
// One of the processes still has a session open and should
|
1132
1127
|
// not be idle cleaned.
|
1133
1128
|
EVENTUALLY(2,
|
@@ -801,7 +801,7 @@ namespace tut {
|
|
801
801
|
{
|
802
802
|
unique_lock<boost::mutex> lock(pool->syncher);
|
803
803
|
origProcess = pool->superGroups.get(wsgiAppPath)->defaultGroup->disablingProcesses.front();
|
804
|
-
ensure(origProcess->
|
804
|
+
ensure(origProcess->oobwStatus == Process::OOBW_REQUESTED);
|
805
805
|
}
|
806
806
|
ensure("sanity check", origPid == origProcess->pid); // just a sanity check
|
807
807
|
|
@@ -822,15 +822,15 @@ namespace tut {
|
|
822
822
|
// Wait for the original process to finish oobw request.
|
823
823
|
EVENTUALLY(2,
|
824
824
|
unique_lock<boost::mutex> lock(pool->syncher);
|
825
|
-
result =
|
825
|
+
result = origProcess->oobwStatus == Process::OOBW_NOT_ACTIVE;
|
826
826
|
);
|
827
827
|
|
828
828
|
// Final asserts.
|
829
829
|
{
|
830
830
|
unique_lock<boost::mutex> lock(pool->syncher);
|
831
|
-
|
832
|
-
|
833
|
-
|
831
|
+
ensure_equals("2 enabled processes", pool->superGroups.get(wsgiAppPath)->defaultGroup->enabledProcesses.size(), 2u);
|
832
|
+
ensure_equals("oobw is reset", origProcess->oobwStatus, Process::OOBW_NOT_ACTIVE);
|
833
|
+
ensure_equals("process is enabled", origProcess->enabled, Process::ENABLED);
|
834
834
|
}
|
835
835
|
}
|
836
836
|
|
@@ -187,6 +187,68 @@ describe RequestHandler do
|
|
187
187
|
end
|
188
188
|
end
|
189
189
|
|
190
|
+
it "catches exceptions generated by the Rack application object" do
|
191
|
+
@options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
|
192
|
+
include Rack::ThreadHandlerExtension
|
193
|
+
end
|
194
|
+
|
195
|
+
lambda_called = false
|
196
|
+
|
197
|
+
# Here we test that the exception is not propagated to outside the request handler.
|
198
|
+
DebugLogging.log_level = -2
|
199
|
+
@options["app"] = lambda do |env|
|
200
|
+
lambda_called = true
|
201
|
+
raise "an error"
|
202
|
+
end
|
203
|
+
|
204
|
+
@request_handler = RequestHandler.new(@owner_pipe[1], @options)
|
205
|
+
@request_handler.start_main_loop_thread
|
206
|
+
client = connect
|
207
|
+
begin
|
208
|
+
send_binary_request(client,
|
209
|
+
"REQUEST_METHOD" => "GET",
|
210
|
+
"PATH_INFO" => "/")
|
211
|
+
client.read
|
212
|
+
ensure
|
213
|
+
client.close
|
214
|
+
end
|
215
|
+
|
216
|
+
lambda_called.should == true
|
217
|
+
end
|
218
|
+
|
219
|
+
it "catches exceptions generated by the Rack body object" do
|
220
|
+
@options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
|
221
|
+
include Rack::ThreadHandlerExtension
|
222
|
+
end
|
223
|
+
|
224
|
+
lambda_called = false
|
225
|
+
|
226
|
+
# Here we test that the exception is not propagated to outside the request handler.
|
227
|
+
DebugLogging.log_level = -2
|
228
|
+
@options["app"] = lambda do |env|
|
229
|
+
lambda_called = true
|
230
|
+
body = Object.new
|
231
|
+
def body.each
|
232
|
+
raise "an error"
|
233
|
+
end
|
234
|
+
[200, { "Content-Type" => "text/plain" }, body]
|
235
|
+
end
|
236
|
+
|
237
|
+
@request_handler = RequestHandler.new(@owner_pipe[1], @options)
|
238
|
+
@request_handler.start_main_loop_thread
|
239
|
+
client = connect
|
240
|
+
begin
|
241
|
+
send_binary_request(client,
|
242
|
+
"REQUEST_METHOD" => "GET",
|
243
|
+
"PATH_INFO" => "/")
|
244
|
+
client.read
|
245
|
+
ensure
|
246
|
+
client.close
|
247
|
+
end
|
248
|
+
|
249
|
+
lambda_called.should == true
|
250
|
+
end
|
251
|
+
|
190
252
|
it "allows the application to take over the socket completely through the full hijack API" do
|
191
253
|
@options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
|
192
254
|
include Rack::ThreadHandlerExtension
|
@@ -265,7 +327,151 @@ describe RequestHandler do
|
|
265
327
|
lambda_called.should == true
|
266
328
|
hijack_callback_called.should == true
|
267
329
|
end
|
268
|
-
|
330
|
+
|
331
|
+
describe "on GET requests that may have a body" do
|
332
|
+
before :each do
|
333
|
+
@options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
|
334
|
+
include Rack::ThreadHandlerExtension
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
it "allows reading from the client socket" do
|
339
|
+
lambda_called = false
|
340
|
+
|
341
|
+
@options["app"] = lambda do |env|
|
342
|
+
lambda_called = true
|
343
|
+
env['rack.input'].read(3).should == "abc"
|
344
|
+
[200, {}, ["ok"]]
|
345
|
+
end
|
346
|
+
|
347
|
+
@request_handler = RequestHandler.new(@owner_pipe[1], @options)
|
348
|
+
@request_handler.start_main_loop_thread
|
349
|
+
client = connect
|
350
|
+
begin
|
351
|
+
send_binary_request(client,
|
352
|
+
"REQUEST_METHOD" => "GET",
|
353
|
+
"PATH_INFO" => "/",
|
354
|
+
"CONTENT_LENGTH" => "3")
|
355
|
+
client.write("abc")
|
356
|
+
client.close_write
|
357
|
+
client.read.should ==
|
358
|
+
"Status: 200\r\n" +
|
359
|
+
"\r\n" +
|
360
|
+
"ok"
|
361
|
+
ensure
|
362
|
+
client.close
|
363
|
+
end
|
364
|
+
|
365
|
+
lambda_called.should be_true
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
describe "on GET requests that are not supposed to have a body" do
|
370
|
+
before :each do
|
371
|
+
@options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
|
372
|
+
include Rack::ThreadHandlerExtension
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
it "disallows reading from the client socket" do
|
377
|
+
lambda_called = false
|
378
|
+
|
379
|
+
@options["app"] = lambda do |env|
|
380
|
+
lambda_called = true
|
381
|
+
env['rack.input'].read(1).should be_nil
|
382
|
+
env['rack.input'].gets.should be_nil
|
383
|
+
[200, {}, ["ok"]]
|
384
|
+
end
|
385
|
+
|
386
|
+
@request_handler = RequestHandler.new(@owner_pipe[1], @options)
|
387
|
+
@request_handler.start_main_loop_thread
|
388
|
+
client = connect
|
389
|
+
begin
|
390
|
+
send_binary_request(client,
|
391
|
+
"REQUEST_METHOD" => "GET",
|
392
|
+
"PATH_INFO" => "/")
|
393
|
+
client.close_write
|
394
|
+
client.read.should ==
|
395
|
+
"Status: 200\r\n" +
|
396
|
+
"\r\n" +
|
397
|
+
"ok"
|
398
|
+
ensure
|
399
|
+
client.close
|
400
|
+
end
|
401
|
+
|
402
|
+
lambda_called.should be_true
|
403
|
+
end
|
404
|
+
|
405
|
+
it "allows reading from the client socket once the socket has been fully hijacked" do
|
406
|
+
lambda_called = false
|
407
|
+
|
408
|
+
@options["app"] = lambda do |env|
|
409
|
+
lambda_called = true
|
410
|
+
env['rack.hijack'].call
|
411
|
+
io = env['rack.hijack_io']
|
412
|
+
begin
|
413
|
+
io.read.should == "hi"
|
414
|
+
io.write("ok")
|
415
|
+
ensure
|
416
|
+
io.close
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
@request_handler = RequestHandler.new(@owner_pipe[1], @options)
|
421
|
+
@request_handler.start_main_loop_thread
|
422
|
+
client = connect
|
423
|
+
begin
|
424
|
+
send_binary_request(client,
|
425
|
+
"REQUEST_METHOD" => "GET",
|
426
|
+
"PATH_INFO" => "/")
|
427
|
+
client.write("hi")
|
428
|
+
client.close_write
|
429
|
+
client.read.should == "ok"
|
430
|
+
ensure
|
431
|
+
client.close
|
432
|
+
end
|
433
|
+
|
434
|
+
lambda_called.should be_true
|
435
|
+
end
|
436
|
+
|
437
|
+
it "allows reading from the client socket once the socket has been partially hijacked" do
|
438
|
+
lambda_called = false
|
439
|
+
|
440
|
+
@options["app"] = lambda do |env|
|
441
|
+
block = lambda do |io|
|
442
|
+
lambda_called = true
|
443
|
+
begin
|
444
|
+
io.read.should == "hi"
|
445
|
+
io.write("ok")
|
446
|
+
ensure
|
447
|
+
io.close
|
448
|
+
end
|
449
|
+
end
|
450
|
+
headers = { 'rack.hijack' => block }
|
451
|
+
[200, headers, []]
|
452
|
+
end
|
453
|
+
|
454
|
+
@request_handler = RequestHandler.new(@owner_pipe[1], @options)
|
455
|
+
@request_handler.start_main_loop_thread
|
456
|
+
client = connect
|
457
|
+
begin
|
458
|
+
send_binary_request(client,
|
459
|
+
"REQUEST_METHOD" => "GET",
|
460
|
+
"PATH_INFO" => "/")
|
461
|
+
client.write("hi")
|
462
|
+
client.close_write
|
463
|
+
client.read.should ==
|
464
|
+
"Status: 200\r\n" +
|
465
|
+
"\r\n" +
|
466
|
+
"ok"
|
467
|
+
ensure
|
468
|
+
client.close
|
469
|
+
end
|
470
|
+
|
471
|
+
lambda_called.should be_true
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
269
475
|
describe "if analytics logger is given" do
|
270
476
|
def preinitialize
|
271
477
|
if @agent_pid
|
data/test/ruby/spec_helper.rb
CHANGED
@@ -16,7 +16,17 @@ rescue Errno::ENOENT
|
|
16
16
|
exit 1
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
def boolean_option(name, default_value = false)
|
20
|
+
value = ENV[name]
|
21
|
+
if value.nil? || value.empty?
|
22
|
+
return default_value
|
23
|
+
else
|
24
|
+
return value == "yes" || value == "on" || value == "true" || value == "1"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
DEBUG = boolean_option('DEBUG')
|
29
|
+
TEST_CLASSIC_RAILS = boolean_option('TEST_CLASSIC_RAILS', true)
|
20
30
|
AGENTS_DIR = "#{source_root}/agents"
|
21
31
|
|
22
32
|
$LOAD_PATH.unshift("#{source_root}/lib")
|
@@ -36,7 +36,7 @@ Listen 127.0.0.1:<%= @port %>
|
|
36
36
|
LoadModule passenger_module "<%= @mod_passenger %>"
|
37
37
|
|
38
38
|
PassengerRoot "<%= @passenger_root %>"
|
39
|
-
|
39
|
+
PassengerDefaultRuby "<%= PlatformInfo.ruby_command %>"
|
40
40
|
PassengerDefaultUser <%= CONFIG['default_user'] %>
|
41
41
|
PassengerDefaultGroup <%= CONFIG['default_group'] %>
|
42
42
|
PassengerTempDir "<%= @passenger_temp_dir %>"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passenger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.
|
4
|
+
version: 4.0.0.rc6
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -60,7 +60,7 @@ dependencies:
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
description: Easy and robust Ruby web application deployment.
|
63
|
-
email:
|
63
|
+
email: software-signing@phusion.nl
|
64
64
|
executables:
|
65
65
|
- passenger
|
66
66
|
- passenger-install-apache2-module
|
@@ -243,6 +243,7 @@ files:
|
|
243
243
|
- doc/users_guide_snippets/installation.txt
|
244
244
|
- doc/users_guide_snippets/passenger_spawn_method.txt
|
245
245
|
- doc/users_guide_snippets/rackup_specifications.txt
|
246
|
+
- doc/users_guide_snippets/rvm_helper_tool.txt
|
246
247
|
- doc/users_guide_snippets/since_version.txt
|
247
248
|
- doc/users_guide_snippets/support_information.txt
|
248
249
|
- doc/users_guide_snippets/tips.txt
|
@@ -2201,6 +2202,7 @@ files:
|
|
2201
2202
|
- ext/ruby/extconf.rb
|
2202
2203
|
- dev/copy_boost_headers.rb
|
2203
2204
|
- dev/find_owner_pipe_leaks.rb
|
2205
|
+
- dev/googlecode_upload.py
|
2204
2206
|
- dev/render_error_pages.rb
|
2205
2207
|
- dev/run_travis.sh
|
2206
2208
|
- resources/mime.types
|
metadata.gz.asc
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
-----BEGIN PGP SIGNATURE-----
|
2
|
+
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
|
+
Comment: GPGTools - http://gpgtools.org
|
4
|
+
|
5
|
+
iQEcBAABAgAGBQJRZAnsAAoJECrHRaUKISqMnUkIALsTpow4UO6t7iY6uyUeVQg6
|
6
|
+
We42umF91RGnAIPF/jhXwEhK5bmwxGgzYte8BBk79oh5U5+Y5WM4WwSnnKLRbiBO
|
7
|
+
34SbieXr8gCSoPZIP8Jz34Zn6h7Rit+ETcasFkrq+PojmyeNeE+0ygU/nY+3GoQR
|
8
|
+
5tx8M6wvpPhbjpbiWOqmf+kf5SJT3Kx6bLrJveHd+HEzQS6Gek8d8uif+d/hi3AT
|
9
|
+
oUt/1L9AA/qX7H3ucuVNUA2ohMjuX1+vtFqezK6h6GcVwDvy91aepLGuCWn/TA2f
|
10
|
+
wbExtgfZ8DHrW6y/whEbiii21ZlVohpIpbxshnu4/LtEYG42kkNM3ExgeoPV9/s=
|
11
|
+
=EKr1
|
12
|
+
-----END PGP SIGNATURE-----
|