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.
- data/NEWS +137 -0
- data/Rakefile +101 -19
- data/bin/passenger-install-nginx-module +10 -3
- data/bin/passenger-make-enterprisey +1 -1
- data/doc/Users guide Apache.html +227 -92
- data/doc/Users guide Apache.txt +169 -75
- data/doc/Users guide Nginx.html +1 -1
- data/doc/cxxapi/Bucket_8h-source.html +1 -1
- data/doc/cxxapi/Configuration_8h-source.html +373 -338
- data/doc/cxxapi/DirectoryMapper_8h-source.html +1 -1
- data/doc/cxxapi/Hooks_8h-source.html +1 -1
- data/doc/cxxapi/annotated.html +1 -1
- data/doc/cxxapi/classHooks-members.html +1 -1
- data/doc/cxxapi/classHooks.html +2 -2
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +1 -1
- data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +1 -1
- data/doc/cxxapi/classes.html +1 -1
- data/doc/cxxapi/definitions_8h-source.html +1 -1
- data/doc/cxxapi/files.html +1 -1
- data/doc/cxxapi/functions.html +1 -1
- data/doc/cxxapi/functions_func.html +1 -1
- data/doc/cxxapi/graph_legend.html +1 -1
- data/doc/cxxapi/group__Configuration.html +1 -1
- data/doc/cxxapi/group__Core.html +1 -1
- data/doc/cxxapi/group__Hooks.html +1 -1
- data/doc/cxxapi/group__Support.html +1 -1
- data/doc/cxxapi/main.html +1 -1
- data/doc/cxxapi/modules.html +1 -1
- data/doc/rdoc/classes/ConditionVariable.html +59 -59
- data/doc/rdoc/classes/Exception.html +11 -11
- data/doc/rdoc/classes/GC.html +4 -4
- data/doc/rdoc/classes/IO.html +14 -14
- data/doc/rdoc/classes/PhusionPassenger.html +1 -1
- data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +8 -8
- data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +136 -136
- data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +254 -254
- data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +61 -61
- data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +4 -4
- data/doc/rdoc/classes/PhusionPassenger/Application.html +14 -14
- data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +12 -12
- data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +4 -4
- data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +12 -12
- data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +5 -5
- data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +139 -139
- data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +61 -56
- data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +3 -3
- data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +7 -7
- data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +15 -15
- data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +119 -119
- data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +4 -4
- data/doc/rdoc/classes/PhusionPassenger/Utils.html +310 -312
- data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +169 -0
- data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +4 -4
- data/doc/rdoc/classes/PlatformInfo.html +165 -164
- data/doc/rdoc/classes/Signal.html +23 -23
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +26 -28
- data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +26 -28
- data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +26 -28
- data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +26 -28
- data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +1 -2
- data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +1 -1
- data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +26 -28
- data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +26 -28
- data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +34 -36
- data/doc/rdoc/fr_class_index.html +1 -0
- data/doc/rdoc/fr_method_index.html +72 -68
- data/ext/apache2/Configuration.cpp +69 -15
- data/ext/apache2/Configuration.h +37 -2
- data/ext/apache2/Hooks.cpp +167 -59
- data/ext/common/ApplicationPoolServerExecutable.cpp +1 -1
- data/ext/common/MessageChannel.h +4 -4
- data/ext/common/StandardApplicationPool.h +1 -1
- data/ext/common/Timer.h +2 -0
- data/ext/common/Version.h +1 -1
- data/ext/nginx/Configuration.c +3 -3
- data/ext/nginx/ContentHandler.c +16 -4
- data/ext/nginx/HelperServer.cpp +1 -1
- data/ext/oxt/system_calls.cpp +6 -1
- data/ext/oxt/thread.hpp +17 -2
- data/ext/phusion_passenger/native_support.c +4 -4
- data/lib/phusion_passenger/abstract_request_handler.rb +3 -3
- data/lib/phusion_passenger/abstract_server.rb +1 -0
- data/lib/phusion_passenger/constants.rb +1 -1
- data/lib/phusion_passenger/message_channel.rb +1 -0
- data/lib/phusion_passenger/platform_info.rb +3 -2
- data/lib/phusion_passenger/rack/request_handler.rb +11 -7
- data/lib/phusion_passenger/railz/application_spawner.rb +7 -4
- data/lib/phusion_passenger/railz/request_handler.rb +1 -0
- data/lib/phusion_passenger/spawn_manager.rb +1 -0
- data/lib/phusion_passenger/utils.rb +38 -20
- data/test/integration_tests/apache2_tests.rb +162 -100
- data/test/integration_tests/mycook_spec.rb +63 -62
- data/test/integration_tests/nginx_tests.rb +12 -5
- data/test/ruby/utils_spec.rb +98 -14
- data/test/stub/apache2/httpd.conf.erb +2 -1
- data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +8 -0
- data/test/support/apache2_controller.rb +5 -1
- data/test/support/test_helper.rb +42 -13
- 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 "
|
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
|
-
@
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
@apache2.set_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
|
-
@
|
156
|
-
|
157
|
-
@apache2.set_vhost('passenger.test',
|
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 #{
|
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
|
-
@
|
168
|
-
@
|
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://
|
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 =
|
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 =
|
241
|
+
@server = @mycook_url_root
|
183
242
|
get('/welcome/rails_env').should == "production"
|
184
243
|
|
185
|
-
@server =
|
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 =
|
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 =
|
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 =
|
201
|
-
controller = "#{@
|
202
|
-
restart_file = "#{@
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
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
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
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
|
-
|
229
|
-
|
230
|
-
|
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 =
|
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("#{@
|
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?("#{@
|
261
|
-
!File.exist?("#{@
|
262
|
-
!File.exist?("#{@
|
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("#{@
|
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("#{@
|
299
|
-
File.open("#{@
|
300
|
-
File.open("#{@
|
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 =
|
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("#{@
|
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?("#{@
|
325
|
-
!File.exist?("#{@
|
326
|
-
!File.exist?("#{@
|
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("#{@
|
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("#{@
|
363
|
-
File.open("#{@
|
364
|
-
File.open("#{@
|
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 :
|
373
|
-
@
|
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
|
-
|
16
|
-
|
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 "
|
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
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
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
|
-
|
142
|
-
|
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.
|
158
|
-
|
159
|
-
|
160
|
-
|
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
|
-
|
166
|
-
|
167
|
-
|
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')
|