passenger 3.0.9 → 3.0.10

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 (67) hide show
  1. data/NEWS +32 -0
  2. data/Rakefile +1 -1
  3. data/build/common_library.rb +6 -1
  4. data/build/config.rb +3 -1
  5. data/doc/Users guide Apache.html +120 -39
  6. data/doc/Users guide Apache.txt +64 -0
  7. data/doc/Users guide Nginx.html +50 -2
  8. data/doc/Users guide Nginx.txt +29 -0
  9. data/ext/apache2/Bucket.cpp +7 -5
  10. data/ext/apache2/Bucket.h +2 -1
  11. data/ext/apache2/Configuration.cpp +8 -0
  12. data/ext/apache2/Configuration.hpp +9 -5
  13. data/ext/apache2/HelperAgent.cpp +4 -5
  14. data/ext/apache2/Hooks.cpp +1 -6
  15. data/ext/boost/thread/exceptions.hpp +7 -1
  16. data/ext/boost/thread/locks.hpp +11 -11
  17. data/ext/common/AgentBase.cpp +21 -1
  18. data/ext/common/AgentsStarter.hpp +22 -21
  19. data/ext/common/ApplicationPool/Client.h +0 -8
  20. data/ext/common/ApplicationPool/Server.h +22 -21
  21. data/ext/common/Constants.h +1 -1
  22. data/ext/common/EventedMessageServer.h +6 -2
  23. data/ext/common/IniFile.h +4 -4
  24. data/ext/common/Logging.h +1 -1
  25. data/ext/common/LoggingAgent/LoggingServer.h +2 -2
  26. data/ext/common/LoggingAgent/Main.cpp +2 -2
  27. data/ext/common/MessageChannel.h +20 -62
  28. data/ext/common/MessageReadersWriters.h +4 -4
  29. data/ext/common/MessageServer.h +18 -18
  30. data/ext/common/Process.h +4 -5
  31. data/ext/common/Session.h +6 -40
  32. data/ext/common/SpawnManager.h +20 -25
  33. data/ext/common/Utils.cpp +1 -1
  34. data/ext/common/Utils/Dechunker.h +1 -1
  35. data/ext/common/Utils/MessageIO.h +109 -14
  36. data/ext/common/Utils/StreamBoyerMooreHorspool.h +20 -14
  37. data/ext/common/Utils/VariantMap.h +9 -27
  38. data/ext/common/Watchdog.cpp +53 -42
  39. data/ext/libev/config.h +122 -0
  40. data/ext/nginx/Configuration.c +62 -0
  41. data/ext/nginx/Configuration.h +5 -0
  42. data/ext/nginx/ContentHandler.c +46 -19
  43. data/ext/nginx/HelperAgent.cpp +6 -5
  44. data/ext/nginx/config +12 -12
  45. data/ext/oxt/system_calls.cpp +10 -1
  46. data/ext/ruby/extconf.rb +0 -1
  47. data/ext/ruby/passenger_native_support.c +2 -2
  48. data/helper-scripts/prespawn +1 -1
  49. data/lib/phusion_passenger.rb +4 -4
  50. data/lib/phusion_passenger/classic_rails/application_spawner.rb +2 -2
  51. data/lib/phusion_passenger/dependencies.rb +6 -1
  52. data/lib/phusion_passenger/platform_info.rb +9 -0
  53. data/lib/phusion_passenger/platform_info/compiler.rb +5 -0
  54. data/lib/phusion_passenger/platform_info/operating_system.rb +1 -1
  55. data/lib/phusion_passenger/platform_info/ruby.rb +5 -5
  56. data/lib/phusion_passenger/rack/application_spawner.rb +6 -3
  57. data/lib/phusion_passenger/utils.rb +2 -2
  58. data/lib/phusion_passenger/wsgi/application_spawner.rb +1 -1
  59. data/resources/mime.types +2 -0
  60. data/test/cxx/LoggingTest.cpp +10 -12
  61. data/test/cxx/MessageIOTest.cpp +53 -3
  62. data/test/cxx/MessageReadersWritersTest.cpp +5 -2
  63. data/test/cxx/MessageServerTest.cpp +3 -1
  64. data/test/integration_tests/nginx_tests.rb +14 -1
  65. data/test/stub/rack/config.ru +2 -0
  66. data/test/tut/tut.h +9 -3
  67. metadata +5 -4
@@ -334,6 +334,15 @@ public
334
334
  end
335
335
  end
336
336
  private_class_method :try_compile_and_run
337
+
338
+ def self.rb_config
339
+ if defined?(::RbConfig)
340
+ return ::RbConfig::CONFIG
341
+ else
342
+ return ::Config::CONFIG
343
+ end
344
+ end
345
+ private_class_method :rb_config
337
346
  end
338
347
 
339
348
  end # module PhusionPassenger
@@ -61,6 +61,11 @@ module PlatformInfo
61
61
  end
62
62
  memoize :compiler_supports_wno_attributes_flag?, true
63
63
 
64
+ def self.compiler_supports_wno_missing_field_initializers_flag?
65
+ return try_compile(:c, '', '-Wno-missing-field-initializers')
66
+ end
67
+ memoize :compiler_supports_wno_missing_field_initializers_flag?
68
+
64
69
  # Returns whether compiling C++ with -fvisibility=hidden might result
65
70
  # in tons of useless warnings, like this:
66
71
  # http://code.google.com/p/phusion-passenger/issues/detail?id=526
@@ -30,7 +30,7 @@ module PlatformInfo
30
30
  # Returns the operating system's name. This name is in lowercase and contains no spaces,
31
31
  # and thus is suitable to be used in some kind of ID. E.g. "linux", "macosx".
32
32
  def self.os_name
33
- if Config::CONFIG['target_os'] =~ /darwin/ && (sw_vers = find_command('sw_vers'))
33
+ if rb_config['target_os'] =~ /darwin/ && (sw_vers = find_command('sw_vers'))
34
34
  return "macosx"
35
35
  else
36
36
  return RUBY_PLATFORM.sub(/.*?-/, '')
@@ -93,7 +93,7 @@ module PlatformInfo
93
93
  # interpreter; use ruby_command instead.
94
94
  def self.ruby_executable
95
95
  @@ruby_executable ||=
96
- Config::CONFIG['bindir'] + '/' + Config::CONFIG['RUBY_INSTALL_NAME'] + Config::CONFIG['EXEEXT']
96
+ rb_config['bindir'] + '/' + rb_config['RUBY_INSTALL_NAME'] + rb_config['EXEEXT']
97
97
  end
98
98
 
99
99
  # Returns whether the Ruby interpreter supports process forking.
@@ -103,7 +103,7 @@ module PlatformInfo
103
103
  return Process.respond_to?(:fork) &&
104
104
  RUBY_ENGINE != "jruby" &&
105
105
  RUBY_ENGINE != "macruby" &&
106
- Config::CONFIG['target_os'] !~ /mswin|windows|mingw/
106
+ rb_config['target_os'] !~ /mswin|windows|mingw/
107
107
  end
108
108
 
109
109
  # Returns the correct 'gem' command for this Ruby interpreter.
@@ -152,7 +152,7 @@ module PlatformInfo
152
152
 
153
153
  # Returns whether the current Ruby interpreter is managed by RVM.
154
154
  def self.in_rvm?
155
- bindir = Config::CONFIG['bindir']
155
+ bindir = rb_config['bindir']
156
156
  return bindir.include?('/.rvm/') || bindir.include?('/rvm/')
157
157
  end
158
158
 
@@ -246,7 +246,7 @@ module PlatformInfo
246
246
  def self.locate_ruby_tool(name)
247
247
  result = locate_ruby_tool_by_basename(name)
248
248
  if !result
249
- exeext = Config::CONFIG['EXEEXT']
249
+ exeext = rb_config['EXEEXT']
250
250
  exeext = nil if exeext.empty?
251
251
  if exeext
252
252
  result = locate_ruby_tool_by_basename("#{name}#{exeext}")
@@ -324,7 +324,7 @@ private
324
324
  #
325
325
  # transform_according_to_ruby_exec_format("rake") => "jrake", "rake1.8", etc
326
326
  def self.transform_according_to_ruby_exec_format(name)
327
- install_name = Config::CONFIG['RUBY_INSTALL_NAME']
327
+ install_name = rb_config['RUBY_INSTALL_NAME']
328
328
  if install_name.include?('ruby')
329
329
  format = install_name.sub('ruby', '%s')
330
330
  return sprintf(format, name)
@@ -1,3 +1,4 @@
1
+ # encoding: binary
1
2
  # Phusion Passenger - http://www.modrails.com/
2
3
  # Copyright (c) 2010 Phusion
3
4
  #
@@ -151,7 +152,7 @@ protected
151
152
  # Overrided method.
152
153
  def initialize_server # :nodoc:
153
154
  report_app_init_status(MessageChannel.new(@owner_socket)) do
154
- $0 = "Passenger ApplicationSpawner: #{@app_root}"
155
+ $0 = "Passenger ApplicationSpawner: #{@options['app_group_name']}"
155
156
  prepare_app_process('config.ru', @options)
156
157
  @app = self.class.send(:load_rack_app)
157
158
  after_loading_app_code(@options)
@@ -189,7 +190,7 @@ private
189
190
 
190
191
  def self.start_request_handler(channel, app, forked, options)
191
192
  app_root = options["app_root"]
192
- $0 = "Rack: #{app_root}"
193
+ $0 = "Rack: #{options['app_group_name']}"
193
194
  reader, writer = IO.pipe
194
195
  begin
195
196
  reader.close_on_exec!
@@ -218,7 +219,9 @@ private
218
219
  # Rails apps explicitly specify a Rack version as dependency.
219
220
  require 'rack'
220
221
  rackup_file = ENV["RACKUP_FILE"] || "config.ru"
221
- rackup_code = ::File.read(rackup_file)
222
+ rackup_code = ::File.open(rackup_file, 'rb') do |f|
223
+ f.read
224
+ end
222
225
  eval("Rack::Builder.new {( #{rackup_code}\n )}.to_app", TOPLEVEL_BINDING, rackup_file)
223
226
  end
224
227
  private_class_method :load_rack_app
@@ -330,7 +330,7 @@ protected
330
330
  # attempt to un-require RubyGems, so here we put Phusion Passenger back
331
331
  # into the load path. This must be done before loading the app's startup
332
332
  # file because the app might require() Phusion Passenger files.
333
- if $LOAD_PATH.first != LIBDIR
333
+ if !$LOAD_PATH.include?(LIBDIR)
334
334
  $LOAD_PATH.unshift(LIBDIR)
335
335
  $LOAD_PATH.uniq!
336
336
  end
@@ -359,7 +359,7 @@ protected
359
359
  # load path after setting up Bundler, the app itself might also
360
360
  # remove Phusion Passenger from the load path for whatever reason,
361
361
  # so here we restore the load path again.
362
- if $LOAD_PATH.first != LIBDIR
362
+ if !$LOAD_PATH.include?(LIBDIR)
363
363
  $LOAD_PATH.unshift(LIBDIR)
364
364
  $LOAD_PATH.uniq!
365
365
  end
@@ -70,7 +70,7 @@ class ApplicationSpawner
70
70
 
71
71
  private
72
72
  def run(channel, options)
73
- $0 = "WSGI: #{options['app_root']}"
73
+ $0 = "WSGI: #{options['app_group_name']}"
74
74
  prepare_app_process("passenger_wsgi.py", options)
75
75
  ENV['WSGI_ENV'] = options['environment']
76
76
 
data/resources/mime.types CHANGED
@@ -8,6 +8,7 @@ types {
8
8
  application/x-javascript js;
9
9
  application/atom+xml atom;
10
10
  application/rss+xml rss;
11
+ text/cache-manifest manifest appcache;
11
12
 
12
13
  text/mathml mml;
13
14
  text/plain txt;
@@ -57,6 +58,7 @@ types {
57
58
  application/octet-stream eot;
58
59
  application/octet-stream iso img;
59
60
  application/octet-stream msi msp msm;
61
+ application/octet-stream gem;
60
62
 
61
63
  audio/midi mid midi kar;
62
64
  audio/mpeg mp3;
@@ -1,7 +1,8 @@
1
1
  #include "TestSupport.h"
2
- #include "Logging.h"
3
- #include "MessageClient.h"
4
- #include "LoggingAgent/LoggingServer.h"
2
+ #include <Logging.h>
3
+ #include <MessageClient.h>
4
+ #include <LoggingAgent/LoggingServer.h>
5
+ #include <Utils/MessageIO.h>
5
6
 
6
7
  #include <boost/bind.hpp>
7
8
  #include <boost/shared_ptr.hpp>
@@ -565,9 +566,8 @@ namespace tut {
565
566
  log.reset();
566
567
 
567
568
  vector<string> args;
568
- MessageChannel channel(logger->getConnection());
569
- channel.write("flush", NULL);
570
- ensure(channel.read(args));
569
+ writeArrayMessage(logger->getConnection(), "flush", NULL);
570
+ ensure(readArrayMessage(logger->getConnection(), args));
571
571
  ensure_equals(args.size(), 1u);
572
572
  ensure_equals(args[0], "ok");
573
573
 
@@ -591,13 +591,11 @@ namespace tut {
591
591
  log2->message("message 2");
592
592
  log2.reset();
593
593
 
594
- MessageChannel channel(logger->getConnection());
595
- channel.write("flush", NULL);
596
- ensure(channel.read(args));
594
+ writeArrayMessage(logger->getConnection(), "flush", NULL);
595
+ ensure(readArrayMessage(logger->getConnection(), args));
597
596
 
598
- channel = MessageChannel(logger2->getConnection());
599
- channel.write("flush", NULL);
600
- ensure(channel.read(args));
597
+ writeArrayMessage(logger2->getConnection(), "flush", NULL);
598
+ ensure(readArrayMessage(logger2->getConnection(), args));
601
599
 
602
600
  string filename = loggingDir + "/1/" FOOBAR_LOCALHOST_PREFIX "/requests/2010/01/12/12/log.txt";
603
601
  struct stat buf;
@@ -155,7 +155,7 @@ namespace tut {
155
155
  /***** Test readArrayMessage() and writeArrayMessage() *****/
156
156
 
157
157
  TEST_METHOD(20) {
158
- // They work.
158
+ // Test <= 10 arguments.
159
159
  writeArrayMessage(pipes[1], "ab", "cd", "efg", NULL);
160
160
  writeArrayMessage(pipes[1], "ab", "cd", "efh", NULL);
161
161
 
@@ -182,6 +182,56 @@ namespace tut {
182
182
  }
183
183
 
184
184
  TEST_METHOD(21) {
185
+ // Test > 10 arguments.
186
+ writeArrayMessage(pipes[1], "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "a", "b", NULL);
187
+ writeArrayMessage(pipes[1], "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", NULL);
188
+
189
+ unsigned char buf[26];
190
+ readExact(pipes[0], buf, 26);
191
+ ensure_equals(buf[0], 0u);
192
+ ensure_equals(buf[1], 24u);
193
+ ensure_equals(buf[2], '1');
194
+ ensure_equals(buf[3], '\0');
195
+ ensure_equals(buf[4], '2');
196
+ ensure_equals(buf[5], '\0');
197
+ ensure_equals(buf[6], '3');
198
+ ensure_equals(buf[7], '\0');
199
+ ensure_equals(buf[8], '4');
200
+ ensure_equals(buf[9], '\0');
201
+ ensure_equals(buf[10], '5');
202
+ ensure_equals(buf[11], '\0');
203
+ ensure_equals(buf[12], '6');
204
+ ensure_equals(buf[13], '\0');
205
+ ensure_equals(buf[14], '7');
206
+ ensure_equals(buf[15], '\0');
207
+ ensure_equals(buf[16], '8');
208
+ ensure_equals(buf[17], '\0');
209
+ ensure_equals(buf[18], '9');
210
+ ensure_equals(buf[19], '\0');
211
+ ensure_equals(buf[20], '0');
212
+ ensure_equals(buf[21], '\0');
213
+ ensure_equals(buf[22], 'a');
214
+ ensure_equals(buf[23], '\0');
215
+ ensure_equals(buf[24], 'b');
216
+ ensure_equals(buf[25], '\0');
217
+
218
+ vector<string> args = readArrayMessage(pipes[0]);
219
+ ensure_equals(args.size(), 12u);
220
+ ensure_equals(args[0], "c");
221
+ ensure_equals(args[1], "d");
222
+ ensure_equals(args[2], "e");
223
+ ensure_equals(args[3], "f");
224
+ ensure_equals(args[4], "g");
225
+ ensure_equals(args[5], "h");
226
+ ensure_equals(args[6], "i");
227
+ ensure_equals(args[7], "j");
228
+ ensure_equals(args[8], "k");
229
+ ensure_equals(args[9], "l");
230
+ ensure_equals(args[10], "m");
231
+ ensure_equals(args[11], "n");
232
+ }
233
+
234
+ TEST_METHOD(22) {
185
235
  // readArrayMessage() throws EOFException on premature EOF.
186
236
  writeExact(pipes[1], "\x00");
187
237
  pipes[1].close();
@@ -201,7 +251,7 @@ namespace tut {
201
251
  }
202
252
  }
203
253
 
204
- TEST_METHOD(22) {
254
+ TEST_METHOD(23) {
205
255
  // Test timeout.
206
256
  unsigned long long timeout = 30000;
207
257
  unsigned long long startTime = SystemTime::getUsec();
@@ -228,7 +278,7 @@ namespace tut {
228
278
  }
229
279
  }
230
280
 
231
- /***** Test readArrayMessage() and writeArrayMessage() *****/
281
+ /***** Test readScalarMessage() and writeScalarMessage() *****/
232
282
 
233
283
  TEST_METHOD(30) {
234
284
  // They work.
@@ -1,5 +1,7 @@
1
1
  #include "TestSupport.h"
2
- #include "MessageReadersWriters.h"
2
+ #include <MessageReadersWriters.h>
3
+ #include <cstdlib>
4
+ #include <alloca.h>
3
5
 
4
6
  using namespace Passenger;
5
7
  using namespace std;
@@ -382,7 +384,8 @@ namespace tut {
382
384
  TEST_METHOD(34) {
383
385
  // generate() works.
384
386
  StaticString args[] = { "ab", "cde" };
385
- StaticString out[ArrayMessage::outputSize(2)];
387
+ StaticString *out = (StaticString *)
388
+ alloca(ArrayMessage::outputSize(2) * sizeof(StaticString));
386
389
  char buf[sizeof(uint16_t)];
387
390
  ArrayMessage::generate(args, 2, buf, out, ArrayMessage::outputSize(2));
388
391
 
@@ -42,6 +42,7 @@ namespace tut {
42
42
  if (serverThread != NULL) {
43
43
  serverThread->interrupt_and_join();
44
44
  }
45
+ Passenger::setLogLevel(0);
45
46
  }
46
47
 
47
48
  class SlowClient: public Client {
@@ -180,7 +181,8 @@ namespace tut {
180
181
  TEST_METHOD(3) {
181
182
  // It disconnects the client if the client does not supply a username and
182
183
  // password within a time limit.
183
- server->setLoginTimeout(40);
184
+ Passenger::setLogLevel(-1);
185
+ server->setLoginTimeout(40000);
184
186
 
185
187
  /* These can throw either an IOException or SystemException:
186
188
  * - An IOException is raised when connect() encounters EOF.
@@ -40,7 +40,6 @@ describe "Phusion Passenger for Nginx" do
40
40
  end
41
41
  end
42
42
 
43
-
44
43
  describe "MyCook(tm) beta running a root URI" do
45
44
  before :all do
46
45
  @server = "http://1.passenger.test:#{@nginx.port}"
@@ -108,6 +107,7 @@ describe "Phusion Passenger for Nginx" do
108
107
  @nginx.add_server do |server|
109
108
  server[:server_name] = "passenger.test"
110
109
  server[:root] = "#{@stub.full_app_root}/public"
110
+ server[:passenger_max_requests] = 3
111
111
  end
112
112
  @nginx.start
113
113
  end
@@ -193,6 +193,11 @@ describe "Phusion Passenger for Nginx" do
193
193
  server[:passenger_app_group_name] = "secondary"
194
194
  server[:passenger_show_version_in_header] = "off"
195
195
  end
196
+ @nginx.add_server do |server|
197
+ server[:server_name] = "2.passenger.test"
198
+ server[:root] = "#{@stub.full_app_root}/public"
199
+ server[:passenger_max_requests] = 3
200
+ end
196
201
  @nginx.start
197
202
  end
198
203
 
@@ -247,6 +252,14 @@ describe "Phusion Passenger for Nginx" do
247
252
  response["X-Powered-By"].should include("Phusion Passenger")
248
253
  response["X-Powered-By"].should_not include(PhusionPassenger::VERSION_STRING)
249
254
  end
255
+
256
+ it "respawns the app after handling max_requests requests" do
257
+ @server = "http://2.passenger.test:#{@nginx.port}/"
258
+ pid = get("/pid")
259
+ get("/pid").should == pid
260
+ get("/pid").should == pid
261
+ get("/pid").should_not == pid
262
+ end
250
263
  end
251
264
 
252
265
 
@@ -2,6 +2,8 @@ app = lambda do |env|
2
2
  if env['PATH_INFO'] == '/chunked'
3
3
  chunks = ["7\r\nchunk1\n\r\n", "7\r\nchunk2\n\r\n", "7\r\nchunk3\n\r\n", "0\r\n\r\n"]
4
4
  [200, { "Content-Type" => "text/html", "Transfer-Encoding" => "chunked" }, chunks]
5
+ elsif env['PATH_INFO'] == '/pid'
6
+ [200, { "Content-Type" => "text/html" }, [$$]]
5
7
  else
6
8
  [200, { "Content-Type" => "text/html" }, ["hello <b>world</b>"]]
7
9
  end
data/test/tut/tut.h CHANGED
@@ -69,9 +69,15 @@ static int setenv(const char *name, const char *value, int override) {
69
69
  typedef factory::object object; \
70
70
  factory name## _group(#name)
71
71
 
72
- #define TEST_METHOD(i) \
73
- template<> template<> \
74
- void object::test<i>()
72
+ #ifdef __clang__
73
+ #define TEST_METHOD(i) \
74
+ template<> \
75
+ void object::test<i>()
76
+ #else
77
+ #define TEST_METHOD(i) \
78
+ template<> template<> \
79
+ void object::test<i>()
80
+ #endif
75
81
 
76
82
  /**
77
83
  * Template Unit Tests Framework for C++.
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passenger
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 9
10
- version: 3.0.9
9
+ - 10
10
+ version: 3.0.10
11
11
  platform: ruby
12
12
  authors:
13
13
  - Phusion - http://www.phusion.nl/
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-04 00:00:00 +02:00
18
+ date: 2011-11-26 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -1076,6 +1076,7 @@ files:
1076
1076
  - ext/libev/ltmain.sh
1077
1077
  - ext/libev/missing
1078
1078
  - ext/libev/mkinstalldirs
1079
+ - ext/libev/config.h
1079
1080
  - ext/libev/ev++.h
1080
1081
  - ext/libev/ev.h
1081
1082
  - ext/libev/ev_vars.h