passenger 4.0.38 → 4.0.39

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 (39) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.asc +7 -7
  3. data.tar.gz.asc +7 -7
  4. data/CHANGELOG +24 -0
  5. data/bin/passenger +5 -0
  6. data/bin/passenger-install-apache2-module +1 -1
  7. data/bin/passenger-install-nginx-module +1 -1
  8. data/build/apache2.rb +2 -6
  9. data/build/cxx_tests.rb +5 -0
  10. data/build/packaging.rb +1 -0
  11. data/dev/list_tests.rb +36 -0
  12. data/doc/Users guide Standalone.txt +20 -5
  13. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +6 -13
  14. data/ext/common/Constants.h +1 -1
  15. data/ext/common/MessageClient.h +7 -7
  16. data/ext/common/Utils.cpp +6 -2
  17. data/ext/common/Utils/MessageIO.h +6 -11
  18. data/ext/common/agents/HelperAgent/RequestHandler.cpp +6 -3
  19. data/ext/common/agents/HelperAgent/RequestHandler.h +146 -24
  20. data/ext/ruby/extconf.rb +12 -0
  21. data/ext/ruby/passenger_native_support.c +18 -13
  22. data/helper-scripts/wsgi-loader.py +25 -2
  23. data/lib/phusion_passenger.rb +1 -1
  24. data/lib/phusion_passenger/config/about_command.rb +3 -0
  25. data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -4
  26. data/lib/phusion_passenger/request_handler/thread_handler.rb +0 -21
  27. data/lib/phusion_passenger/standalone/command.rb +10 -3
  28. data/lib/phusion_passenger/standalone/start_command.rb +4 -0
  29. data/lib/phusion_passenger/utils/tee_input.rb +82 -14
  30. data/lib/phusion_passenger/utils/terminal_choice_menu.rb +17 -2
  31. data/lib/phusion_passenger/utils/unseekable_socket.rb +0 -30
  32. data/resources/templates/error_layout.html.template +1 -1
  33. data/resources/templates/standalone/config.erb +18 -5
  34. data/test/cxx/RequestHandlerTest.cpp +410 -194
  35. data/test/integration_tests/native_packaging_spec.rb +5 -1
  36. data/test/ruby/request_handler_spec.rb +4 -71
  37. data/test/ruby/utils/tee_input_spec.rb +235 -0
  38. metadata +5 -3
  39. metadata.gz.asc +7 -7
@@ -113,7 +113,11 @@ describe "A natively packaged Phusion Passenger" do
113
113
  if $?.exitstatus == 0
114
114
  return output
115
115
  else
116
- abort "Command #{command} exited with status #{$?.exitstatus}"
116
+ filename = `mktemp /tmp/output.XXXXXX`.strip
117
+ File.open(filename, "w") do |f|
118
+ f.write(output)
119
+ end
120
+ abort "Command #{command} exited with status #{$?.exitstatus}. Output written to #{filename}"
117
121
  end
118
122
  end
119
123
 
@@ -328,7 +328,7 @@ describe RequestHandler do
328
328
  hijack_callback_called.should == true
329
329
  end
330
330
 
331
- specify "GET requests with Content-Length are assumed to have a request body" do
331
+ specify "requests with Content-Length are assumed to have a request body" do
332
332
  @options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
333
333
  include Rack::ThreadHandlerExtension
334
334
  end
@@ -362,7 +362,7 @@ describe RequestHandler do
362
362
  lambda_called.should be_true
363
363
  end
364
364
 
365
- specify "GET requests with Transfer-Encoding are assumed to have a request body" do
365
+ specify "requests with Transfer-Encoding chunked are assumed to have a request body" do
366
366
  @options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
367
367
  include Rack::ThreadHandlerExtension
368
368
  end
@@ -402,7 +402,7 @@ describe RequestHandler do
402
402
  lambda_called.should be_true
403
403
  end
404
404
 
405
- specify "GET requests with neither Content-Length nor Transfer-Encoding are assumed to have no request body" do
405
+ specify "requests with neither Content-Length nor Transfer-Encoding are assumed to have no request body" do
406
406
  @options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
407
407
  include Rack::ThreadHandlerExtension
408
408
  end
@@ -416,72 +416,6 @@ describe RequestHandler do
416
416
  [200, {}, ["ok"]]
417
417
  end
418
418
 
419
- @request_handler = RequestHandler.new(@owner_pipe[1], @options)
420
- @request_handler.start_main_loop_thread
421
- client = connect
422
- begin
423
- send_binary_request(client,
424
- "REQUEST_METHOD" => "GET",
425
- "PATH_INFO" => "/")
426
- client.close_write
427
- client.read.should ==
428
- "Status: 200\r\n" +
429
- "\r\n" +
430
- "ok"
431
- ensure
432
- client.close
433
- end
434
-
435
- lambda_called.should be_true
436
- end
437
-
438
- specify "GET requests with Content-Length 0 are assumed to have no request body" do
439
- @options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
440
- include Rack::ThreadHandlerExtension
441
- end
442
-
443
- lambda_called = false
444
-
445
- @options["app"] = lambda do |env|
446
- lambda_called = true
447
- env['rack.input'].read(1).should be_nil
448
- env['rack.input'].gets.should be_nil
449
- [200, {}, ["ok"]]
450
- end
451
-
452
- @request_handler = RequestHandler.new(@owner_pipe[1], @options)
453
- @request_handler.start_main_loop_thread
454
- client = connect
455
- begin
456
- send_binary_request(client,
457
- "REQUEST_METHOD" => "GET",
458
- "PATH_INFO" => "/",
459
- "CONTENT_LENGTH" => "0")
460
- client.close_write
461
- client.read.should ==
462
- "Status: 200\r\n" +
463
- "\r\n" +
464
- "ok"
465
- ensure
466
- client.close
467
- end
468
-
469
- lambda_called.should be_true
470
- end
471
-
472
- specify "non-GET requests are assumed to have a request body, even those without Content-Length and Transfer-Encoding" do
473
- @options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
474
- include Rack::ThreadHandlerExtension
475
- end
476
-
477
- lambda_called = false
478
-
479
- @options["app"] = lambda do |env|
480
- lambda_called = true
481
- env['rack.input'].read(3).should == "abc"
482
- [200, {}, ["ok"]]
483
- end
484
-
485
419
  @request_handler = RequestHandler.new(@owner_pipe[1], @options)
486
420
  @request_handler.start_main_loop_thread
487
421
  client = connect
@@ -489,7 +423,6 @@ describe RequestHandler do
489
423
  send_binary_request(client,
490
424
  "REQUEST_METHOD" => "POST",
491
425
  "PATH_INFO" => "/")
492
- client.write("abc")
493
426
  client.close_write
494
427
  client.read.should ==
495
428
  "Status: 200\r\n" +
@@ -502,7 +435,7 @@ describe RequestHandler do
502
435
  lambda_called.should be_true
503
436
  end
504
437
 
505
- describe "on GET requests that are not supposed to have a body" do
438
+ describe "on requests that are not supposed to have a body" do
506
439
  before :each do
507
440
  @options["thread_handler"] = Class.new(RequestHandler::ThreadHandler) do
508
441
  include Rack::ThreadHandlerExtension
@@ -0,0 +1,235 @@
1
+ # encoding: binary
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+ PhusionPassenger.require_passenger_lib 'utils/tee_input'
4
+ require 'stringio'
5
+
6
+ module PhusionPassenger
7
+
8
+ shared_examples "TeeInput#gets" do
9
+ context "if Content-Length is given" do
10
+ before :each do
11
+ init_input("hello\nworld\nlast line!", "CONTENT_LENGTH" => 21)
12
+ end
13
+
14
+ it "reads a line, including newline character" do
15
+ @input.gets.should == "hello\n"
16
+ @input.gets.should == "world\n"
17
+ end
18
+
19
+ it "reads until EOF if no newline is encountered before EOF" do
20
+ @input.gets
21
+ @input.gets
22
+ @input.gets.should == "last line"
23
+ end
24
+
25
+ it "returns nil if EOF is reached" do
26
+ @input.gets
27
+ @input.gets
28
+ @input.gets
29
+ @input.gets.should be_nil
30
+ end
31
+ end
32
+
33
+ context "if Transfer-Encoding is chunked" do
34
+ before :each do
35
+ init_input("hello\nworld\nlast line", "HTTP_TRANSFER_ENCODING" => "chunked")
36
+ end
37
+
38
+ it "reads a line, including newline character" do
39
+ @input.gets.should == "hello\n"
40
+ @input.gets.should == "world\n"
41
+ end
42
+
43
+ it "reads until EOF if no newline is encountered before EOF" do
44
+ @input.gets
45
+ @input.gets
46
+ @input.gets.should == "last line"
47
+ end
48
+
49
+ it "returns nil if EOF is reached" do
50
+ @input.gets
51
+ @input.gets
52
+ @input.gets
53
+ @input.gets.should be_nil
54
+ end
55
+ end
56
+
57
+ context "if neither Content-Length nor Transfer-Encoding chunked are given" do
58
+ before :each do
59
+ init_input("hello\nworld\nlast line")
60
+ end
61
+
62
+ it "returns nil" do
63
+ @input.gets.should be_nil
64
+ end
65
+ end
66
+ end
67
+
68
+ shared_examples "TeeInput#read" do
69
+ describe "with no arguments" do
70
+ context "if Content-Length is given" do
71
+ before :each do
72
+ init_input("hello!", "CONTENT_LENGTH" => 5)
73
+ end
74
+
75
+ it "slurps up to Content-Length bytes from the socket" do
76
+ @input.read.should == "hello"
77
+ end
78
+
79
+ it "returns the empty string if EOF is reached" do
80
+ @input.read
81
+ @input.read.should == ""
82
+ end
83
+ end
84
+
85
+ context "if Transfer-Encoding is chunked" do
86
+ before :each do
87
+ init_input("hello!", "HTTP_TRANSFER_ENCODING" => "chunked")
88
+ end
89
+
90
+ it "slurps the entire socket" do
91
+ @input.read.should == "hello!"
92
+ end
93
+
94
+ it "returns the empty string if EOF is reached" do
95
+ @input.read
96
+ @input.read.should == ""
97
+ end
98
+ end
99
+
100
+ context "if neither Content-Length nor Transfer-Encoding chunked are given" do
101
+ before :each do
102
+ init_input("hello!")
103
+ end
104
+
105
+ it "returns the empty string" do
106
+ @input.read.should == ""
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "with a length argument" do
112
+ it "raises ArgumentError if len < 0" do
113
+ init_input("")
114
+ lambda { @input.read(-1) }.should raise_error(ArgumentError)
115
+ end
116
+
117
+ it "returns the empty string if len == 0" do
118
+ init_input("hello", "HTTP_TRANSFER_ENCODING" => "chunked")
119
+ @input.read(0).should == ""
120
+ end
121
+
122
+ context "if Content-Length is given" do
123
+ before :each do
124
+ init_input("hello!", "CONTENT_LENGTH" => 5)
125
+ end
126
+
127
+ it "reads exactly len bytes if available" do
128
+ @input.read(2).should == "he"
129
+ @input.read(2).should == "ll"
130
+ end
131
+
132
+ it "reads at most Content-Length bytes if Content-Length < len are available" do
133
+ @input.read(2).should == "he"
134
+ @input.read(4).should == "llo"
135
+ end
136
+
137
+ it "returns nil if Content-Length is reached" do
138
+ @input.read(5).should == "hello"
139
+ @input.read(1).should be_nil
140
+ end
141
+ end
142
+
143
+ context "if Transfer-Encoding is chunked" do
144
+ before :each do
145
+ init_input("hello", "HTTP_TRANSFER_ENCODING" => "chunked")
146
+ end
147
+
148
+ it "reads exactly len bytes if available" do
149
+ @input.read(2).should == "he"
150
+ @input.read(2).should == "ll"
151
+ end
152
+
153
+ it "reads until EOF if less than len bytes are available" do
154
+ @input.read(2).should == "he"
155
+ @input.read(4).should == "llo"
156
+ end
157
+
158
+ it "returns nil if EOF is reached" do
159
+ @input.read(5).should == "hello"
160
+ @input.read(1).should be_nil
161
+ end
162
+ end
163
+
164
+ context "if neither Content-Length nor Transfer-Encoding chunked are given" do
165
+ it "returns nil" do
166
+ init_input("hello")
167
+ @input.read(2).should be_nil
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ shared_examples "TeeInput#size" do
174
+ context "if Content-Length is given" do
175
+ it "returns the value in Content-Length" do
176
+ init_input("hello world", "CONTENT_LENGTH" => 10)
177
+ @input.size.should == 10
178
+ end
179
+ end
180
+
181
+ context "if Transfer-Encoding is chunked" do
182
+ it "returns the number of bytes that can be read from the socket until EOF" do
183
+ init_input("hello world", "HTTP_TRANSFER_ENCODING" => "chunked")
184
+ @input.size.should == 11
185
+ end
186
+ end
187
+
188
+ context "if neither Content-Length nor Transfer-Encoding chunked are given" do
189
+ it "returns 0" do
190
+ init_input("hello world")
191
+ @input.size.should == 0
192
+ end
193
+ end
194
+ end
195
+
196
+ describe Utils::TeeInput do
197
+ before :each do
198
+ @sock, @sock2 = UNIXSocket.pair
199
+ end
200
+
201
+ after :each do
202
+ [@sock, @sock2].each do |sock|
203
+ sock.close if sock && !sock.closed?
204
+ end
205
+ @input.close if @input
206
+ end
207
+
208
+ context "when unbuffered" do
209
+ def init_input(data, env = {})
210
+ @input = Utils::TeeInput.new(@sock2, env)
211
+ @sock.write(data)
212
+ @sock.close
213
+ end
214
+
215
+ describe("#gets") { include_examples "TeeInput#gets" }
216
+ describe("#read") { include_examples "TeeInput#read" }
217
+ describe("#size") { include_examples "TeeInput#size" }
218
+ end
219
+
220
+ context "when buffered" do
221
+ def init_input(data, env = {})
222
+ @input = Utils::TeeInput.new(@sock2, env)
223
+ @sock.write(data)
224
+ @sock.close
225
+ @input.read
226
+ @input.rewind
227
+ end
228
+
229
+ describe("#gets") { include_examples "TeeInput#gets" }
230
+ describe("#read") { include_examples "TeeInput#read" }
231
+ describe("#size") { include_examples "TeeInput#size" }
232
+ end
233
+ end
234
+
235
+ end # module PhusionPassenger
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passenger
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.38
4
+ version: 4.0.39
5
5
  platform: ruby
6
6
  authors:
7
7
  - Phusion - http://www.phusion.nl/
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-10 00:00:00.000000000 Z
11
+ date: 2014-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -124,6 +124,7 @@ files:
124
124
  - dev/copy_boost_headers.rb
125
125
  - dev/find_owner_pipe_leaks.rb
126
126
  - dev/install_scripts_bootstrap_code.rb
127
+ - dev/list_tests.rb
127
128
  - dev/render_error_pages.rb
128
129
  - dev/run_travis.sh
129
130
  - dev/runner
@@ -2576,6 +2577,7 @@ files:
2576
2577
  - test/ruby/standalone/runtime_locator_spec.rb
2577
2578
  - test/ruby/utils/file_system_watcher_spec.rb
2578
2579
  - test/ruby/utils/hosts_file_parser.rb
2580
+ - test/ruby/utils/tee_input_spec.rb
2579
2581
  - test/ruby/utils/unseekable_socket_spec.rb
2580
2582
  - test/ruby/utils_spec.rb
2581
2583
  - test/stub/.DS_Store
@@ -2938,7 +2940,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
2938
2940
  version: '0'
2939
2941
  requirements: []
2940
2942
  rubyforge_project: passenger
2941
- rubygems_version: 2.2.0
2943
+ rubygems_version: 2.2.2
2942
2944
  signing_key:
2943
2945
  specification_version: 4
2944
2946
  summary: A fast and robust web server and application server for Ruby, Python and
metadata.gz.asc CHANGED
@@ -2,11 +2,11 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQEcBAABAgAGBQJTHZ8DAAoJECrHRaUKISqMCBkH/2dM97EYCl9cBd0oqVJJU9gj
6
- w1j01aSvR51w8a5SAMxi+upIggPQ2AGW4bcCDt/MZ9LUgKwWN2FlkHo7I5YhUEt9
7
- pKrF9AaYdaWAaUwb/s++f0pT7YYJim+ANxmjGiahZBW3Cmbxtgr08JdS/lzKc7sq
8
- bndmFbAIA/QKAzkK0MiGrz4bD33zmvDlXeNpg2emvwkk9YYGCxMMEfVex13Ob+wY
9
- xnNn4H9CdLCPL3Yhb1uA/xvhjqWteFthmdkcNvALSrJZ2KySck0kDFOudA0HwDW5
10
- kLUpZjb7Qusq2bNlKpRZtKr9BPTnyJcUAn32PI0ZL8jmg1JNG+q1MDgDjz4rTQM=
11
- =toG+
5
+ iQEcBAABAgAGBQJTKAuvAAoJECrHRaUKISqMJV0H/jJ3TdSzvcOED6fM21+rWEUZ
6
+ GwCLToeTuTnXM8kazH/A/+k+Gc1taW3TqdD6Ovu6iJftsrAt+nnfWY23Eo2+X47R
7
+ mwYRWSx1e9nJ+oeiTR/hzo+0swQ+HUR31Fu5sN0dqhptddyEfr6lvvpWY0C71tf9
8
+ o9WL3UP6uZqFJs3fSMW5F+mbC+mqjhJLC1dCzoAq+l18TW6zrkkpFdmhKqQ+z/Q0
9
+ E2u6TyDmIXfyU9proT8Qi/yjV/jhMhFpw19ENAWB1SzFZ/06ZcOy86YqSj4BYScA
10
+ uli9v4gcArgNtDZLE3IogSIQrRQVST7XKhdP0bpZlx5nzkOeWPU+8HS3dK2ZH14=
11
+ =oBMO
12
12
  -----END PGP SIGNATURE-----