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.

Files changed (83) hide show
  1. data.tar.gz.asc +12 -0
  2. data/.travis.yml +4 -4
  3. data/NEWS +46 -0
  4. data/bin/passenger-config +31 -1
  5. data/bin/passenger-install-apache2-module +1 -1
  6. data/bin/passenger-install-nginx-module +1 -0
  7. data/build/common_library.rb +4 -0
  8. data/build/cplusplus_support.rb +27 -6
  9. data/build/cxx_tests.rb +1 -1
  10. data/build/misc.rb +28 -6
  11. data/build/packaging.rb +72 -65
  12. data/build/test_basics.rb +1 -1
  13. data/dev/googlecode_upload.py +265 -0
  14. data/dev/run_travis.sh +9 -0
  15. data/doc/Users guide Apache.html +376 -193
  16. data/doc/Users guide Apache.idmap.txt +80 -62
  17. data/doc/Users guide Apache.txt +61 -35
  18. data/doc/Users guide Nginx.html +278 -83
  19. data/doc/Users guide Nginx.idmap.txt +26 -10
  20. data/doc/Users guide Nginx.txt +59 -31
  21. data/doc/Users guide Standalone.html +1 -1
  22. data/doc/users_guide_snippets/installation.txt +121 -11
  23. data/doc/users_guide_snippets/rvm_helper_tool.txt +56 -0
  24. data/ext/apache2/Bucket.cpp +1 -1
  25. data/ext/apache2/Configuration.cpp +7 -1
  26. data/ext/apache2/Configuration.hpp +4 -0
  27. data/ext/apache2/Hooks.cpp +2 -2
  28. data/ext/common/AgentsStarter.cpp +2 -2
  29. data/ext/common/AgentsStarter.h +1 -1
  30. data/ext/common/AgentsStarter.hpp +2 -2
  31. data/ext/common/ApplicationPool2/DirectSpawner.h +4 -8
  32. data/ext/common/ApplicationPool2/Group.h +17 -11
  33. data/ext/common/ApplicationPool2/Implementation.cpp +39 -11
  34. data/ext/common/ApplicationPool2/Pool.h +23 -4
  35. data/ext/common/ApplicationPool2/Process.h +30 -11
  36. data/ext/common/ApplicationPool2/SmartSpawner.h +3 -1
  37. data/ext/common/Constants.h +1 -1
  38. data/ext/common/EventedBufferedInput.h +4 -0
  39. data/ext/common/Utils.cpp +21 -3
  40. data/ext/common/Utils.h +8 -1
  41. data/ext/common/Utils/HttpHeaderBufferer.h +1 -1
  42. data/ext/common/Utils/IOUtils.cpp +5 -4
  43. data/ext/common/Utils/IOUtils.h +32 -14
  44. data/ext/common/Utils/MessagePassing.h +2 -2
  45. data/ext/common/Utils/ProcessMetricsCollector.h +47 -15
  46. data/ext/common/Utils/ScopeGuard.h +20 -3
  47. data/ext/common/Utils/StrIntUtils.h +14 -5
  48. data/ext/common/agents/Base.cpp +161 -50
  49. data/ext/common/agents/HelperAgent/AgentOptions.h +2 -2
  50. data/ext/common/agents/HelperAgent/Main.cpp +1 -0
  51. data/ext/common/agents/HelperAgent/RequestHandler.h +166 -52
  52. data/ext/common/agents/LoggingAgent/Main.cpp +1 -1
  53. data/ext/common/agents/Watchdog/Main.cpp +2 -2
  54. data/ext/nginx/Configuration.c +31 -4
  55. data/ext/nginx/Configuration.h +1 -0
  56. data/ext/nginx/ContentHandler.c +148 -34
  57. data/ext/nginx/ngx_http_passenger_module.c +4 -1
  58. data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
  59. data/ext/oxt/macros.hpp +30 -8
  60. data/lib/phusion_passenger.rb +2 -2
  61. data/lib/phusion_passenger/classic_rails/thread_handler_extension.rb +1 -1
  62. data/lib/phusion_passenger/native_support.rb +19 -1
  63. data/lib/phusion_passenger/platform_info/compiler.rb +6 -0
  64. data/lib/phusion_passenger/platform_info/ruby.rb +54 -5
  65. data/lib/phusion_passenger/preloader_shared_helpers.rb +8 -1
  66. data/lib/phusion_passenger/rack/out_of_band_gc.rb +3 -1
  67. data/lib/phusion_passenger/rack/thread_handler_extension.rb +32 -5
  68. data/lib/phusion_passenger/request_handler/thread_handler.rb +28 -8
  69. data/lib/phusion_passenger/ruby_core_enhancements.rb +9 -1
  70. data/lib/phusion_passenger/standalone/runtime_installer.rb +1 -0
  71. data/lib/phusion_passenger/utils/unseekable_socket.rb +50 -5
  72. data/passenger.gemspec +1 -1
  73. data/resources/templates/apache2/config_snippets.txt.erb +1 -1
  74. data/test/cxx/ApplicationPool2/PoolTest.cpp +4 -9
  75. data/test/cxx/RequestHandlerTest.cpp +5 -5
  76. data/test/ruby/classic_rails/loader_spec.rb +1 -1
  77. data/test/ruby/classic_rails/preloader_spec.rb +1 -1
  78. data/test/ruby/request_handler_spec.rb +207 -1
  79. data/test/ruby/shared/loader_sharedspec.rb +1 -0
  80. data/test/ruby/spec_helper.rb +11 -1
  81. data/test/stub/apache2/httpd.conf.erb +1 -1
  82. metadata +5 -3
  83. metadata.gz.asc +12 -0
@@ -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 = "info@phusion.nl"
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>PassengerRuby <%= @ruby %></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->asyncGet(options, callback);
1122
- pool->asyncGet(options, callback);
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->oobwRequested);
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 = !origProcess->oobwRequested;
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
- ensure("2 enabled processes", pool->superGroups.get(wsgiAppPath)->defaultGroup->enabledProcesses.size() == 2);
832
- ensure("oobw is reset", !origProcess->oobwRequested);
833
- ensure("process is enabled", origProcess->enabled == Process::ENABLED);
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
 
@@ -42,6 +42,6 @@ describe "Classic Rails 2.3 loader" do
42
42
  "end of startup file\n" +
43
43
  "worker_process_started: forked=false\n"
44
44
  end
45
- end
45
+ end if TEST_CLASSIC_RAILS
46
46
 
47
47
  end # module PhusionPassenger
@@ -48,6 +48,6 @@ describe "Classic Rails 2.3 preloader" do
48
48
  "end of startup file\n" +
49
49
  "worker_process_started: forked=true\n"
50
50
  end
51
- end
51
+ end if TEST_CLASSIC_RAILS
52
52
 
53
53
  end # module PhusionPassenger
@@ -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
@@ -121,6 +121,7 @@ private
121
121
 
122
122
  if status == "Error\n"
123
123
  body = @output.read
124
+ STDERR.puts "<--- #{body}" if DEBUG
124
125
  end
125
126
 
126
127
  return { :status => status.strip, :headers => headers, :body => body }
@@ -16,7 +16,17 @@ rescue Errno::ENOENT
16
16
  exit 1
17
17
  end
18
18
 
19
- DEBUG = ['1', 'y', 'yes'].include?(ENV['DEBUG'].to_s.downcase)
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
- PassengerRuby "<%= PlatformInfo.ruby_command %>"
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.rc4
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-03-05 00:00:00.000000000 Z
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: info@phusion.nl
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
@@ -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-----