passenger 2.2.4 → 2.2.5

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 (105) hide show
  1. data/NEWS +137 -0
  2. data/Rakefile +101 -19
  3. data/bin/passenger-install-nginx-module +10 -3
  4. data/bin/passenger-make-enterprisey +1 -1
  5. data/doc/Users guide Apache.html +227 -92
  6. data/doc/Users guide Apache.txt +169 -75
  7. data/doc/Users guide Nginx.html +1 -1
  8. data/doc/cxxapi/Bucket_8h-source.html +1 -1
  9. data/doc/cxxapi/Configuration_8h-source.html +373 -338
  10. data/doc/cxxapi/DirectoryMapper_8h-source.html +1 -1
  11. data/doc/cxxapi/Hooks_8h-source.html +1 -1
  12. data/doc/cxxapi/annotated.html +1 -1
  13. data/doc/cxxapi/classHooks-members.html +1 -1
  14. data/doc/cxxapi/classHooks.html +2 -2
  15. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +1 -1
  16. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +1 -1
  17. data/doc/cxxapi/classes.html +1 -1
  18. data/doc/cxxapi/definitions_8h-source.html +1 -1
  19. data/doc/cxxapi/files.html +1 -1
  20. data/doc/cxxapi/functions.html +1 -1
  21. data/doc/cxxapi/functions_func.html +1 -1
  22. data/doc/cxxapi/graph_legend.html +1 -1
  23. data/doc/cxxapi/group__Configuration.html +1 -1
  24. data/doc/cxxapi/group__Core.html +1 -1
  25. data/doc/cxxapi/group__Hooks.html +1 -1
  26. data/doc/cxxapi/group__Support.html +1 -1
  27. data/doc/cxxapi/main.html +1 -1
  28. data/doc/cxxapi/modules.html +1 -1
  29. data/doc/rdoc/classes/ConditionVariable.html +59 -59
  30. data/doc/rdoc/classes/Exception.html +11 -11
  31. data/doc/rdoc/classes/GC.html +4 -4
  32. data/doc/rdoc/classes/IO.html +14 -14
  33. data/doc/rdoc/classes/PhusionPassenger.html +1 -1
  34. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +8 -8
  35. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +136 -136
  36. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +254 -254
  37. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +61 -61
  38. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +4 -4
  39. data/doc/rdoc/classes/PhusionPassenger/Application.html +14 -14
  40. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +12 -12
  41. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +4 -4
  42. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +12 -12
  43. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +5 -5
  44. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +139 -139
  45. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +61 -56
  46. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +3 -3
  47. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +7 -7
  48. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +15 -15
  49. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +119 -119
  50. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +4 -4
  51. data/doc/rdoc/classes/PhusionPassenger/Utils.html +310 -312
  52. data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +169 -0
  53. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +4 -4
  54. data/doc/rdoc/classes/PlatformInfo.html +165 -164
  55. data/doc/rdoc/classes/Signal.html +23 -23
  56. data/doc/rdoc/created.rid +1 -1
  57. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +1 -1
  58. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +26 -28
  59. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +26 -28
  60. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +1 -1
  61. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +1 -1
  62. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +26 -28
  63. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +1 -1
  64. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +1 -1
  65. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +26 -28
  66. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +1 -2
  67. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +1 -1
  68. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +26 -28
  69. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +26 -28
  70. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +34 -36
  71. data/doc/rdoc/fr_class_index.html +1 -0
  72. data/doc/rdoc/fr_method_index.html +72 -68
  73. data/ext/apache2/Configuration.cpp +69 -15
  74. data/ext/apache2/Configuration.h +37 -2
  75. data/ext/apache2/Hooks.cpp +167 -59
  76. data/ext/common/ApplicationPoolServerExecutable.cpp +1 -1
  77. data/ext/common/MessageChannel.h +4 -4
  78. data/ext/common/StandardApplicationPool.h +1 -1
  79. data/ext/common/Timer.h +2 -0
  80. data/ext/common/Version.h +1 -1
  81. data/ext/nginx/Configuration.c +3 -3
  82. data/ext/nginx/ContentHandler.c +16 -4
  83. data/ext/nginx/HelperServer.cpp +1 -1
  84. data/ext/oxt/system_calls.cpp +6 -1
  85. data/ext/oxt/thread.hpp +17 -2
  86. data/ext/phusion_passenger/native_support.c +4 -4
  87. data/lib/phusion_passenger/abstract_request_handler.rb +3 -3
  88. data/lib/phusion_passenger/abstract_server.rb +1 -0
  89. data/lib/phusion_passenger/constants.rb +1 -1
  90. data/lib/phusion_passenger/message_channel.rb +1 -0
  91. data/lib/phusion_passenger/platform_info.rb +3 -2
  92. data/lib/phusion_passenger/rack/request_handler.rb +11 -7
  93. data/lib/phusion_passenger/railz/application_spawner.rb +7 -4
  94. data/lib/phusion_passenger/railz/request_handler.rb +1 -0
  95. data/lib/phusion_passenger/spawn_manager.rb +1 -0
  96. data/lib/phusion_passenger/utils.rb +38 -20
  97. data/test/integration_tests/apache2_tests.rb +162 -100
  98. data/test/integration_tests/mycook_spec.rb +63 -62
  99. data/test/integration_tests/nginx_tests.rb +12 -5
  100. data/test/ruby/utils_spec.rb +98 -14
  101. data/test/stub/apache2/httpd.conf.erb +2 -1
  102. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +8 -0
  103. data/test/support/apache2_controller.rb +5 -1
  104. data/test/support/test_helper.rb +42 -13
  105. metadata +7 -137
@@ -12,7 +12,7 @@ require 'integration_tests/hello_world_wsgi_spec'
12
12
  # TODO: test the 'RailsUserSwitching' and 'RailsDefaultUser' option.
13
13
  # TODO: test custom page caching directory
14
14
 
15
- describe "mod_passenger running in Apache 2" do
15
+ describe "Apache 2 module" do
16
16
  include TestHelper
17
17
 
18
18
  before :all do
@@ -33,9 +33,10 @@ describe "mod_passenger running in Apache 2" do
33
33
  describe ": MyCook(tm) beta running on root URI" do
34
34
  before :all do
35
35
  @web_server_supports_chunked_transfer_encoding = true
36
+ @base_uri = ""
36
37
  @server = "http://passenger.test:#{@apache2.port}"
37
- @stub = setup_rails_stub('mycook')
38
38
  @apache2 << "RailsMaxPoolSize 1"
39
+ @stub = setup_rails_stub('mycook', 'tmp.mycook')
39
40
  @apache2.set_vhost("passenger.test", File.expand_path("#{@stub.app_root}/public"))
40
41
  @apache2.start
41
42
  end
@@ -44,6 +45,10 @@ describe "mod_passenger running in Apache 2" do
44
45
  @stub.destroy
45
46
  end
46
47
 
48
+ before :each do
49
+ @stub.reset
50
+ end
51
+
47
52
  it_should_behave_like "MyCook(tm) beta"
48
53
 
49
54
  it "doesn't block Rails while an upload is in progress" do
@@ -93,23 +98,12 @@ describe "mod_passenger running in Apache 2" do
93
98
  end
94
99
  end
95
100
  end
96
-
97
- it "supports environment variable passing through mod_env" do
98
- begin
99
- File.open("#{@stub.app_root}/public/.htaccess", 'w') do |f|
100
- f.puts 'SetEnv FOO "Foo Bar!"'
101
- end
102
- File.touch("#{@stub.app_root}/tmp/restart.txt")
103
- get('/welcome/environment').should =~ /FOO = Foo Bar\!/
104
- ensure
105
- File.unlink("#{@stub.app_root}/public/.htaccess") rescue nil
106
- end
107
- end
108
101
  end
109
102
 
110
103
  describe ": MyCook(tm) beta running in a sub-URI" do
111
104
  before :all do
112
105
  @web_server_supports_chunked_transfer_encoding = true
106
+ @base_uri = "/mycook"
113
107
  @stub = setup_rails_stub('mycook')
114
108
  FileUtils.rm_rf('tmp.webdir')
115
109
  FileUtils.mkdir_p('tmp.webdir')
@@ -129,6 +123,7 @@ describe "mod_passenger running in Apache 2" do
129
123
 
130
124
  before :each do
131
125
  @server = "http://passenger.test:#{@apache2.port}/mycook"
126
+ @stub.reset
132
127
  end
133
128
 
134
129
  it_should_behave_like "MyCook(tm) beta"
@@ -139,98 +134,156 @@ describe "mod_passenger running in Apache 2" do
139
134
  end
140
135
  end
141
136
 
137
+ describe "compatibility with other modules" do
138
+ before :all do
139
+ @apache2 << "RailsMaxPoolSize 1"
140
+
141
+ @mycook = setup_rails_stub('mycook', File.expand_path('tmp.mycook'))
142
+ @mycook_url_root = "http://1.passenger.test:#{@apache2.port}"
143
+ @apache2.set_vhost("1.passenger.test", "#{@mycook.app_root}/public") do |vhost|
144
+ vhost << "RewriteEngine on"
145
+ vhost << "RewriteRule ^/rewritten_welcome$ /welcome [PT,QSA,L]"
146
+ vhost << "RewriteRule ^/rewritten_cgi_environment$ /welcome/cgi_environment [PT,QSA,L]"
147
+ end
148
+ @apache2.start
149
+ end
150
+
151
+ after :all do
152
+ @mycook.destroy
153
+ end
154
+
155
+ before :each do
156
+ @mycook.reset
157
+ @server = @mycook_url_root
158
+ end
159
+
160
+ it "supports environment variable passing through mod_env" do
161
+ File.write("#{@mycook.app_root}/public/.htaccess", 'SetEnv FOO "Foo Bar!"')
162
+ File.touch("#{@mycook.app_root}/tmp/restart.txt") # Activate ENV changes.
163
+ get('/welcome/environment').should =~ /FOO = Foo Bar\!/
164
+ get('/welcome/cgi_environment').should =~ /FOO = Foo Bar\!/
165
+ end
166
+
167
+ it "supports mod_rewrite in the virtual host block" do
168
+ get('/rewritten_welcome').should =~ /Welcome to MyCook/
169
+ cgi_envs = get('/rewritten_cgi_environment?foo=bar+baz')
170
+ cgi_envs.should include("REQUEST_URI = /welcome/cgi_environment?foo=bar+baz\n")
171
+ cgi_envs.should include("PATH_INFO = /welcome/cgi_environment\n")
172
+ end
173
+
174
+ it "supports mod_rewrite in .htaccess" do
175
+ File.write("#{@mycook.app_root}/public/.htaccess", %Q{
176
+ RewriteEngine on
177
+ RewriteRule ^htaccess_welcome$ welcome [PT,QSA,L]
178
+ RewriteRule ^htaccess_cgi_environment$ welcome/cgi_environment [PT,QSA,L]
179
+ })
180
+ get('/htaccess_welcome').should =~ /Welcome to MyCook/
181
+ cgi_envs = get('/htaccess_cgi_environment?foo=bar+baz')
182
+ cgi_envs.should include("REQUEST_URI = /welcome/cgi_environment?foo=bar+baz\n")
183
+ cgi_envs.should include("PATH_INFO = /welcome/cgi_environment\n")
184
+ end
185
+ end
186
+
142
187
  describe "configuration options" do
143
188
  before :all do
144
189
  @apache2 << "PassengerMaxPoolSize 3"
145
190
 
146
- @stub = setup_rails_stub('mycook')
147
- rails_dir = File.expand_path(@stub.app_root) + "/public"
148
-
149
- @apache2.set_vhost('mycook.passenger.test', rails_dir)
150
-
151
- @apache2.set_vhost('norails.passenger.test', rails_dir) do |vhost|
191
+ @mycook = setup_rails_stub('mycook', File.expand_path("tmp.mycook"))
192
+ @mycook_url_root = "http://1.passenger.test:#{@apache2.port}"
193
+ @apache2.set_vhost('1.passenger.test', "#{@mycook.app_root}/public") do |vhost|
194
+ vhost << "AllowEncodedSlashes on"
195
+ end
196
+ @apache2.set_vhost('2.passenger.test', "#{@mycook.app_root}/public") do |vhost|
152
197
  vhost << "RailsAutoDetect off"
153
198
  end
154
199
 
155
- @stub2 = setup_rails_stub('foobar', 'tmp.stub2')
156
- rails_dir = File.expand_path(@stub2.app_root) + "/public"
157
- @apache2.set_vhost('passenger.test', rails_dir) do |vhost|
200
+ @foobar = setup_rails_stub('foobar', File.expand_path("tmp.foobar"))
201
+ @foobar_url_root = "http://3.passenger.test:#{@apache2.port}"
202
+ @apache2.set_vhost('3.passenger.test', "#{@foobar.app_root}/public") do |vhost|
158
203
  vhost << "RailsEnv development"
159
204
  vhost << "RailsSpawnMethod conservative"
160
205
  vhost << "PassengerUseGlobalQueue on"
161
- vhost << "PassengerRestartDir #{rails_dir}"
206
+ vhost << "PassengerRestartDir #{@foobar.app_root}/public"
207
+ end
208
+
209
+ @mycook2 = setup_rails_stub('mycook', File.expand_path("tmp.mycook2"))
210
+ @mycook2_url_root = "http://4.passenger.test:#{@apache2.port}"
211
+ @apache2.set_vhost('4.passenger.test', "#{@mycook2.app_root}/sites/some.site/public") do |vhost|
212
+ vhost << "PassengerAppRoot #{@mycook2.app_root}"
162
213
  end
214
+
163
215
  @apache2.start
164
216
  end
165
217
 
166
218
  after :all do
167
- @stub.destroy
168
- @stub2.destroy
219
+ @mycook.destroy
220
+ @foobar.destroy
221
+ @mycook2.destroy
222
+ end
223
+
224
+ before :each do
225
+ @mycook.reset
226
+ @foobar.reset
227
+ @mycook2.reset
169
228
  end
170
229
 
171
230
  it "ignores the Rails application if RailsAutoDetect is off" do
172
- @server = "http://norails.passenger.test:#{@apache2.port}"
231
+ @server = "http://2.passenger.test:#{@apache2.port}"
173
232
  get('/').should_not =~ /MyCook/
174
233
  end
175
234
 
176
235
  specify "setting RailsAutoDetect for one virtual host should not interfere with others" do
177
- @server = "http://mycook.passenger.test:#{@apache2.port}"
236
+ @server = @mycook_url_root
178
237
  get('/').should =~ /MyCook/
179
238
  end
180
239
 
181
240
  specify "RailsEnv is per-virtual host" do
182
- @server = "http://mycook.passenger.test:#{@apache2.port}"
241
+ @server = @mycook_url_root
183
242
  get('/welcome/rails_env').should == "production"
184
243
 
185
- @server = "http://passenger.test:#{@apache2.port}"
244
+ @server = @foobar_url_root
186
245
  get('/foo/rails_env').should == "development"
187
246
  end
188
247
 
189
248
  it "supports conservative spawning" do
190
- @server = "http://passenger.test:#{@apache2.port}"
249
+ @server = @foobar_url_root
250
+ # TODO: I think this assertion is no longer valid now that
251
+ # smart-lv2 is the default spawn method...
191
252
  get('/foo/backtrace').should_not =~ /framework_spawner/
192
253
  end
193
254
 
194
255
  specify "RailsSpawnMethod spawning is per-virtual host" do
195
- @server = "http://mycook.passenger.test:#{@apache2.port}"
256
+ @server = @mycook_url_root
196
257
  get('/welcome/backtrace').should =~ /application_spawner/
197
258
  end
198
259
 
199
260
  it "looks for restart.txt in the directory specified by PassengerRestartDir" do
200
- @server = "http://passenger.test:#{@apache2.port}"
201
- controller = "#{@stub2.app_root}/app/controllers/bar_controller.rb"
202
- restart_file = "#{@stub2.app_root}/public/restart.txt"
203
- begin
204
- File.open(controller, 'w') do |f|
205
- f.write(%Q{
206
- class BarController < ApplicationController
207
- def index
208
- render :text => 'hello world'
209
- end
210
- end
211
- })
261
+ @server = @foobar_url_root
262
+ controller = "#{@foobar.app_root}/app/controllers/bar_controller.rb"
263
+ restart_file = "#{@foobar.app_root}/public/restart.txt"
264
+
265
+ File.write(controller, %Q{
266
+ class BarController < ApplicationController
267
+ def index
268
+ render :text => 'hello world'
269
+ end
212
270
  end
213
-
214
- now = Time.now
215
- File.touch(restart_file, now - 5)
216
- get('/bar').should == "hello world"
217
-
218
- File.open(controller, 'w') do |f|
219
- f.write(%Q{
220
- class BarController < ApplicationController
221
- def index
222
- render :text => 'oh hai'
223
- end
224
- end
225
- })
271
+ })
272
+
273
+ now = Time.now
274
+ File.touch(restart_file, now - 5)
275
+ get('/bar').should == "hello world"
276
+
277
+ File.write(controller, %Q{
278
+ class BarController < ApplicationController
279
+ def index
280
+ render :text => 'oh hai'
281
+ end
226
282
  end
227
-
228
- File.touch(restart_file, now - 10)
229
- get('/bar').should == "oh hai"
230
- ensure
231
- File.unlink(controller) rescue nil
232
- File.unlink(restart_file) rescue nil
233
- end
283
+ })
284
+
285
+ File.touch(restart_file, now - 10)
286
+ get('/bar').should == "oh hai"
234
287
  end
235
288
 
236
289
  describe "PassengerUseGlobalQueue" do
@@ -240,7 +293,7 @@ describe "mod_passenger running in Apache 2" do
240
293
  end
241
294
 
242
295
  it "is off by default" do
243
- @server = "http://mycook.passenger.test:#{@apache2.port}"
296
+ @server = @mycook_url_root
244
297
 
245
298
  # Spawn the application.
246
299
  get('/')
@@ -249,7 +302,7 @@ describe "mod_passenger running in Apache 2" do
249
302
  # Reserve all application pool slots.
250
303
  3.times do |i|
251
304
  thread = Thread.new do
252
- File.unlink("#{@stub.app_root}/#{i}.txt") rescue nil
305
+ File.unlink("#{@mycook.app_root}/#{i}.txt") rescue nil
253
306
  get("/welcome/sleep_until_exists?name=#{i}.txt")
254
307
  end
255
308
  threads << thread
@@ -257,9 +310,9 @@ describe "mod_passenger running in Apache 2" do
257
310
 
258
311
  # Wait until all application instances are waiting
259
312
  # for the quit file.
260
- while !File.exist?("#{@stub.app_root}/waiting_0.txt") ||
261
- !File.exist?("#{@stub.app_root}/waiting_1.txt") ||
262
- !File.exist?("#{@stub.app_root}/waiting_2.txt")
313
+ while !File.exist?("#{@mycook.app_root}/waiting_0.txt") ||
314
+ !File.exist?("#{@mycook.app_root}/waiting_1.txt") ||
315
+ !File.exist?("#{@mycook.app_root}/waiting_2.txt")
263
316
  sleep 0.1
264
317
  end
265
318
 
@@ -284,7 +337,7 @@ describe "mod_passenger running in Apache 2" do
284
337
 
285
338
  # One of the requests should still be blocked
286
339
  # if one application instance frees up.
287
- File.open("#{@stub.app_root}/2.txt", 'w')
340
+ File.open("#{@mycook.app_root}/2.txt", 'w')
288
341
  begin
289
342
  Timeout.timeout(5) do
290
343
  while !first_request_done && !second_request_done
@@ -295,16 +348,16 @@ describe "mod_passenger running in Apache 2" do
295
348
  end
296
349
  (first_request_done || second_request_done).should be_true
297
350
 
298
- File.open("#{@stub.app_root}/0.txt", 'w')
299
- File.open("#{@stub.app_root}/1.txt", 'w')
300
- File.open("#{@stub.app_root}/2.txt", 'w')
351
+ File.open("#{@mycook.app_root}/0.txt", 'w')
352
+ File.open("#{@mycook.app_root}/1.txt", 'w')
353
+ File.open("#{@mycook.app_root}/2.txt", 'w')
301
354
  threads.each do |thread|
302
355
  thread.join
303
356
  end
304
357
  end
305
358
 
306
359
  it "works and is per-virtual host" do
307
- @server = "http://passenger.test:#{@apache2.port}"
360
+ @server = @foobar_url_root
308
361
 
309
362
  # Spawn the application.
310
363
  get('/')
@@ -313,7 +366,7 @@ describe "mod_passenger running in Apache 2" do
313
366
  # Reserve all application pool slots.
314
367
  3.times do |i|
315
368
  thread = Thread.new do
316
- File.unlink("#{@stub2.app_root}/#{i}.txt") rescue nil
369
+ File.unlink("#{@foobar.app_root}/#{i}.txt") rescue nil
317
370
  get("/foo/sleep_until_exists?name=#{i}.txt")
318
371
  end
319
372
  threads << thread
@@ -321,9 +374,9 @@ describe "mod_passenger running in Apache 2" do
321
374
 
322
375
  # Wait until all application instances are waiting
323
376
  # for the quit file.
324
- while !File.exist?("#{@stub2.app_root}/waiting_0.txt") ||
325
- !File.exist?("#{@stub2.app_root}/waiting_1.txt") ||
326
- !File.exist?("#{@stub2.app_root}/waiting_2.txt")
377
+ while !File.exist?("#{@foobar.app_root}/waiting_0.txt") ||
378
+ !File.exist?("#{@foobar.app_root}/waiting_1.txt") ||
379
+ !File.exist?("#{@foobar.app_root}/waiting_2.txt")
327
380
  sleep 0.1
328
381
  end
329
382
 
@@ -347,7 +400,7 @@ describe "mod_passenger running in Apache 2" do
347
400
  second_request_done.should be_false
348
401
 
349
402
  # Both requests should be processed if one application instance frees up.
350
- File.open("#{@stub2.app_root}/2.txt", 'w')
403
+ File.open("#{@foobar.app_root}/2.txt", 'w')
351
404
  begin
352
405
  Timeout.timeout(5) do
353
406
  while !first_request_done || !second_request_done
@@ -359,41 +412,29 @@ describe "mod_passenger running in Apache 2" do
359
412
  first_request_done.should be_true
360
413
  second_request_done.should be_true
361
414
 
362
- File.open("#{@stub2.app_root}/0.txt", 'w')
363
- File.open("#{@stub2.app_root}/1.txt", 'w')
364
- File.open("#{@stub2.app_root}/2.txt", 'w')
415
+ File.open("#{@foobar.app_root}/0.txt", 'w')
416
+ File.open("#{@foobar.app_root}/1.txt", 'w')
417
+ File.open("#{@foobar.app_root}/2.txt", 'w')
365
418
  threads.each do |thread|
366
419
  thread.join
367
420
  end
368
421
  end
369
422
  end
370
423
 
371
- describe "PassengerAppRoot" do
372
- before :all do
373
- @stub3 = setup_rails_stub('mycook', 'tmp.stub3')
374
- doc_root = File.expand_path(@stub3.app_root) + "/sites/some.site/public"
375
- @apache2.set_vhost('passenger.test', doc_root) do |vhost|
376
- vhost << "PassengerAppRoot #{File.expand_path(@stub3.app_root).inspect}"
377
- end
378
- @apache2.start
379
- end
380
-
381
- after :all do
382
- @stub3.destroy
424
+ describe "PassengerAppRoot" do
425
+ before :each do
426
+ @server = @mycook2_url_root
383
427
  end
384
-
428
+
385
429
  it "supports page caching on non-index URIs" do
386
- @server = "http://passenger.test:#{@apache2.port}"
387
430
  get('/welcome/cached.html').should =~ %r{This is the cached version of some.site/public/welcome/cached}
388
431
  end
389
-
432
+
390
433
  it "supports page caching on index URIs" do
391
- @server = "http://passenger.test:#{@apache2.port}"
392
434
  get('/uploads.html').should =~ %r{This is the cached version of some.site/public/uploads}
393
435
  end
394
-
436
+
395
437
  it "works as a rails application" do
396
- @server = "http://passenger.test:#{@apache2.port}"
397
438
  result = get('/welcome/parameters_test?hello=world&recipe[name]=Green+Bananas')
398
439
  result.should =~ %r{<hello>world</hello>}
399
440
  result.should =~ %r{<recipe>}
@@ -401,6 +442,27 @@ describe "mod_passenger running in Apache 2" do
401
442
  end
402
443
  end
403
444
 
445
+ specify "it resolves symlinks in the document root if PassengerResolveSymlinksInDocumentRoot is set" do
446
+ orig_mycook_app_root = @mycook.app_root
447
+ @mycook.move(File.expand_path('tmp.mycook.symlinktest'))
448
+ FileUtils.mkdir_p(orig_mycook_app_root)
449
+ File.symlink("#{@mycook.app_root}/public", "#{orig_mycook_app_root}/public")
450
+ begin
451
+ File.write("#{@mycook.app_root}/public/.htaccess", "PassengerResolveSymlinksInDocumentRoot on")
452
+ @server = @mycook_url_root
453
+ get('/').should =~ /Welcome to MyCook/
454
+ ensure
455
+ FileUtils.rm_rf(orig_mycook_app_root)
456
+ @mycook.move(orig_mycook_app_root)
457
+ end
458
+ end
459
+
460
+ it "supports encoded slashes in the URL if AllowEncodedSlashes is turned on" do
461
+ @server = @mycook_url_root
462
+ File.write("#{@mycook.app_root}/public/.htaccess", "PassengerAllowEncodedSlashes on")
463
+ get('/welcome/show_id/foo%2fbar').should == 'foo/bar'
464
+ end
465
+
404
466
  ####################################
405
467
  end
406
468
 
@@ -12,18 +12,15 @@ shared_examples_for "MyCook(tm) beta" do
12
12
  end
13
13
 
14
14
  it "supports page caching on root/base URIs" do
15
- begin
16
- File.write("#{@stub.app_root}/public/index.html", "This is index.html.")
17
- get('/').should == "This is index.html."
18
- ensure
19
- File.unlink("#{@stub.app_root}/public/index.html") rescue nil
20
- end
15
+ File.write("#{@stub.app_root}/public/index.html", "This is index.html.")
16
+ get('/').should == "This is index.html."
21
17
  end
22
18
 
23
19
  it "doesn't use page caching if the HTTP request is not GET" do
24
20
  post('/welcome/cached').should =~ %r{This content should never be displayed}
25
21
  end
26
22
 
23
+ # TODO: move this to module compatibility tests
27
24
  it "isn't interfered by Rails's default .htaccess dispatcher rules" do
28
25
  get('/welcome/in_passenger').should == 'true'
29
26
  end
@@ -95,55 +92,38 @@ shared_examples_for "MyCook(tm) beta" do
95
92
  end
96
93
  end
97
94
 
98
- it "can properly handle custom headers" do
95
+ it "properly handles custom headers" do
99
96
  response = get_response('/welcome/headers_test')
100
97
  response["X-Foo"].should == "Bar"
101
98
  end
102
-
103
- it "supports %2f in URIs" do
104
- get('/welcome/show_id/foo%2fbar').should == 'foo/bar'
105
- end
106
-
107
- it "has AbstractRequest which returns a request_uri without hostname, with query_string" do
108
- get('/welcome/request_uri?foo=bar%20escaped').should =~ %r{/welcome/request_uri\?foo=bar%20escaped}
109
- end
110
-
99
+
111
100
  it "supports restarting via restart.txt" do
112
- begin
113
- controller = "#{@stub.app_root}/app/controllers/test_controller.rb"
114
- restart_file = "#{@stub.app_root}/tmp/restart.txt"
115
- now = Time.now
116
-
117
- File.open(controller, 'w') do |f|
118
- f.write %q{
119
- class TestController < ApplicationController
120
- layout nil
121
- def index
122
- render :text => "foo"
123
- end
124
- end
125
- }
101
+ controller = "#{@stub.app_root}/app/controllers/test_controller.rb"
102
+ restart_file = "#{@stub.app_root}/tmp/restart.txt"
103
+ now = Time.now
104
+
105
+ File.write(controller, %q{
106
+ class TestController < ApplicationController
107
+ layout nil
108
+ def index
109
+ render :text => "foo"
110
+ end
126
111
  end
127
- File.touch(restart_file, now - 10)
128
- get('/test').should == "foo"
129
-
130
- File.open(controller, 'w') do |f|
131
- f.write %q{
132
- class TestController < ApplicationController
133
- layout nil
134
- def index
135
- render :text => "bar"
136
- end
137
- end
138
- }
112
+ })
113
+ File.touch(restart_file, now - 10)
114
+ get('/test').should == "foo"
115
+
116
+ File.write(controller, %q{
117
+ class TestController < ApplicationController
118
+ layout nil
119
+ def index
120
+ render :text => "bar"
121
+ end
139
122
  end
123
+ })
140
124
 
141
- File.touch(restart_file, now - 5)
142
- get('/test').should == 'bar'
143
- ensure
144
- File.unlink(controller) rescue nil
145
- File.unlink(restart_file) rescue nil
146
- end
125
+ File.touch(restart_file, now - 5)
126
+ get('/test').should == 'bar'
147
127
  end
148
128
 
149
129
  it "does not make the web server crash if the app crashes" do
@@ -154,21 +134,15 @@ shared_examples_for "MyCook(tm) beta" do
154
134
 
155
135
  it "does not conflict with Phusion Passenger if there's a model named 'Passenger'" do
156
136
  Dir.mkdir("#{@stub.app_root}/app/models") rescue nil
157
- File.open("#{@stub.app_root}/app/models/passenger.rb", 'w') do |f|
158
- f.write(%q{
159
- class Passenger
160
- def name
161
- return "Gourry Gabriev"
162
- end
137
+ File.write("#{@stub.app_root}/app/models/passenger.rb", %q{
138
+ class Passenger
139
+ def name
140
+ return "Gourry Gabriev"
163
141
  end
164
- })
165
- end
166
- begin
167
- File.touch("#{@stub.app_root}/tmp/restart.txt")
168
- get('/welcome/passenger_name').should == 'Gourry Gabriev'
169
- ensure
170
- File.unlink("#{@stub.app_root}/app/models/passenger.rb") rescue nil
171
- end
142
+ end
143
+ })
144
+ File.touch("#{@stub.app_root}/tmp/restart.txt")
145
+ get('/welcome/passenger_name').should == 'Gourry Gabriev'
172
146
  end
173
147
 
174
148
  it "sets the 'Status' header" do
@@ -176,6 +150,33 @@ shared_examples_for "MyCook(tm) beta" do
176
150
  response["Status"].should == "404 Not Found"
177
151
  end
178
152
 
153
+ describe "CGI environment variables compliance" do
154
+ specify "REQUEST_URI contains the request URI including query string" do
155
+ cgi_envs = get('/welcome/cgi_environment?foo=escaped%20string')
156
+ cgi_envs.should include("REQUEST_URI = #{@base_uri}/welcome/cgi_environment?foo=escaped%20string\n")
157
+ end
158
+
159
+ specify "PATH_INFO contains the request URI without the base URI and without the query string" do
160
+ cgi_envs = get('/welcome/cgi_environment?foo=escaped%20string')
161
+ cgi_envs.should include("PATH_INFO = /welcome/cgi_environment\n")
162
+ end
163
+
164
+ specify "QUERY_STRING contains the query string" do
165
+ cgi_envs = get('/welcome/cgi_environment?foo=escaped%20string')
166
+ cgi_envs.should include("QUERY_STRING = foo=escaped%20string\n")
167
+ end
168
+
169
+ specify "QUERY_STRING must be present even when there's no query string" do
170
+ cgi_envs = get('/welcome/cgi_environment')
171
+ cgi_envs.should include("QUERY_STRING = \n")
172
+ end
173
+
174
+ specify "SCRIPT_NAME contains the base URI, or the empty string if the app is deployed on the root URI" do
175
+ cgi_envs = get('/welcome/cgi_environment')
176
+ cgi_envs.should include("SCRIPT_NAME = #{@base_uri}\n")
177
+ end
178
+ end
179
+
179
180
  if Process.uid == 0
180
181
  it "runs as an unprivileged user" do
181
182
  post('/welcome/touch')