passenger 4.0.37 → 4.0.38

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.

@@ -374,9 +374,9 @@ private
374
374
  end
375
375
  end
376
376
  else
377
- def check_port(address, port)
377
+ def check_port_with_protocol(address, port, protocol)
378
378
  begin
379
- socket = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0)
379
+ socket = Socket.new(protocol, Socket::Constants::SOCK_STREAM, 0)
380
380
  sockaddr = Socket.pack_sockaddr_in(port, address)
381
381
  begin
382
382
  socket.connect_nonblock(sockaddr)
@@ -403,6 +403,14 @@ private
403
403
  socket.close if socket && !socket.closed?
404
404
  end
405
405
  end
406
+
407
+ def check_port(address, port)
408
+ begin
409
+ check_port_with_protocol(address, port, Socket::Constants::AF_INET)
410
+ rescue Errno::EAFNOSUPPORT
411
+ check_port_with_protocol(address, port, Socket::Constants::AF_INET6)
412
+ end
413
+ end
406
414
  end
407
415
 
408
416
  def check_port_availability
@@ -435,9 +443,11 @@ private
435
443
  else
436
444
  scheme = "http"
437
445
  end
438
- result = "#{scheme}://#{@options[:address]}"
439
- if @options[:port] != 80
440
- result << ":#{@options[:port]}"
446
+ result = "#{scheme}://"
447
+ if @options[:port] == 80
448
+ result << @options[:address]
449
+ else
450
+ result << compose_ip_and_port(@options[:address], @options[:port])
441
451
  end
442
452
  result << "/"
443
453
  return result
@@ -695,7 +705,7 @@ private
695
705
  else
696
706
  port = options[:port]
697
707
  end
698
- return "#{options[:address]}:#{port}"
708
+ return compose_ip_and_port(options[:address], port)
699
709
  end
700
710
  end
701
711
 
@@ -703,7 +713,16 @@ private
703
713
  if options[:socket_file]
704
714
  return "unix:" + File.expand_path(options[:socket_file])
705
715
  else
706
- return "#{options[:address]}:#{options[:ssl_port]}"
716
+ return compose_ip_and_port(options[:address], options[:ssl_port])
717
+ end
718
+ end
719
+
720
+ def compose_ip_and_port(ip, port)
721
+ if ip =~ /:/
722
+ # IPv6
723
+ return "[#{ip}]:#{port}"
724
+ else
725
+ return "#{ip}:#{port}"
707
726
  end
708
727
  end
709
728
 
@@ -54,7 +54,6 @@ class TerminalChoiceMenu
54
54
  @choices = choices.map { |choice| Choice.create(choice) }
55
55
  @pointer = 0
56
56
  @index = index_choices
57
- initialize_terminal_control
58
57
  end
59
58
 
60
59
  def display_choices
@@ -187,27 +186,22 @@ private
187
186
  require 'readline'
188
187
  java_import 'jline.console.ConsoleReader'
189
188
 
190
- def initialize_terminal_control
189
+ def raw_no_echo_mode
191
190
  input = STDIN.to_inputstream
192
191
  output = STDOUT.to_outputstream
193
192
  @console = ConsoleReader.new(input, output)
194
193
  @console.set_history_enabled(false)
195
194
  @console.set_bell_enabled(true)
196
195
  @console.set_pagination_enabled(false)
197
- end
198
-
199
- def raw_no_echo_mode
200
196
  @terminal_state = @console.getEchoCharacter
201
- @console.setEchoCharacter(0)
197
+ @console.setEchoCharacter(0)
202
198
  end
203
199
 
204
200
  def restore_mode
205
201
  @console.setEchoCharacter(@terminal_state)
202
+ @console.get_terminal.restore
206
203
  end
207
204
  else
208
- def initialize_terminal_control
209
- end
210
-
211
205
  def raw_no_echo_mode
212
206
  @terminal_state = `stty -g`
213
207
  system("stty raw -echo -icanon isig")
@@ -12,14 +12,25 @@ class TmpIO < File
12
12
  # creates and returns a new File object. The File is unlinked
13
13
  # immediately, switched to binary mode, and userspace output
14
14
  # buffering is disabled
15
- def self.new(namespace)
15
+ def self.new(namespace, options = nil)
16
+ if options
17
+ mode = options[:mode] || RDWR
18
+ binary = options.fetch(:binary, true)
19
+ suffix = options[:suffix]
20
+ unlink_immediately = options.fetch(:unlink_immediately, true)
21
+ else
22
+ mode = RDWR
23
+ binary = true
24
+ suffix = nil
25
+ unlink_immediately = true
26
+ end
16
27
  fp = begin
17
- super("#{Dir::tmpdir}/#{namespace}-#{rand}", RDWR|CREAT|EXCL, 0600)
28
+ super("#{Dir::tmpdir}/#{namespace}-#{rand(0x100000000).to_s(36)}#{suffix}", mode | CREAT | EXCL, 0600)
18
29
  rescue Errno::EEXIST
19
30
  retry
20
31
  end
21
- unlink(fp.path)
22
- fp.binmode
32
+ unlink(fp.path) if unlink_immediately
33
+ fp.binmode if binary
23
34
  fp.sync = true
24
35
  fp
25
36
  end
data/passenger.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.email = "software-signing@phusion.nl"
16
16
  s.require_paths = ["lib"]
17
17
  s.add_dependency 'rake', '>= 0.8.1'
18
- s.add_dependency 'daemon_controller', '>= 1.1.0'
18
+ s.add_dependency 'daemon_controller', '>= 1.2.0'
19
19
  s.add_dependency 'rack'
20
20
  s.files = Dir[*PhusionPassenger::Packaging::GLOB] -
21
21
  Dir[*PhusionPassenger::Packaging::EXCLUDE_GLOB]
@@ -291,6 +291,12 @@ describe "Apache 2 module" do
291
291
  vhost << "PassengerAppRoot #{@mycook2.full_app_root}"
292
292
  end
293
293
 
294
+ @stub = RackStub.new('rack')
295
+ @stub_url_root = "http://5.passenger.test:#{@apache2.port}"
296
+ @apache2.set_vhost('5.passenger.test', "#{@stub.full_app_root}/public") do |vhost|
297
+ vhost << "PassengerBufferUpload off"
298
+ end
299
+
294
300
  @apache2.start
295
301
  end
296
302
 
@@ -298,6 +304,7 @@ describe "Apache 2 module" do
298
304
  @mycook.destroy
299
305
  @foobar.destroy
300
306
  @mycook2.destroy
307
+ @stub.destroy
301
308
  @apache2.stop if @apache2
302
309
  end
303
310
 
@@ -305,6 +312,7 @@ describe "Apache 2 module" do
305
312
  @mycook.reset
306
313
  @foobar.reset
307
314
  @mycook2.reset
315
+ @stub.reset
308
316
  end
309
317
 
310
318
  specify "RailsEnv is per-virtual host" do
@@ -386,6 +394,32 @@ describe "Apache 2 module" do
386
394
  get('/welcome/show_id/foo%2fbar').should == 'foo/bar'
387
395
  end
388
396
 
397
+ describe "when handling POST requests with 'chunked' transfer encoding, if PassengerBufferUpload is off" do
398
+ it "sets Transfer-Encoding to 'chunked' and removes Content-Length" do
399
+ @uri = URI.parse(@stub_url_root)
400
+ socket = TCPSocket.new(@uri.host, @uri.port)
401
+ begin
402
+ socket.write("POST #{@stub_url_root}/env HTTP/1.1\r\n")
403
+ socket.write("Host: #{@uri.host}:#{@uri.port}\r\n")
404
+ socket.write("Transfer-Encoding: chunked\r\n")
405
+ socket.write("Content-Type: text/plain\r\n")
406
+ socket.write("Connection: close\r\n")
407
+ socket.write("\r\n")
408
+
409
+ chunk = "foo=bar!"
410
+ socket.write("%X\r\n%s\r\n" % [chunk.size, chunk])
411
+ socket.write("0\r\n\r\n")
412
+ socket.flush
413
+
414
+ response = socket.read
415
+ response.should_not include("CONTENT_LENGTH = ")
416
+ response.should include("HTTP_TRANSFER_ENCODING = chunked\n")
417
+ ensure
418
+ socket.close
419
+ end
420
+ end
421
+ end
422
+
389
423
  ####################################
390
424
  end
391
425
 
@@ -72,29 +72,57 @@ shared_examples_for "an example web app" do
72
72
  end
73
73
  end
74
74
 
75
- it "properly handles POST requests with 'chunked' transfer encoding" do
76
- uri = URI.parse(@server)
77
- socket = TCPSocket.new(uri.host, uri.port)
78
- begin
79
- socket.write("POST #{base_uri}/raw_upload_to_file HTTP/1.1\r\n")
80
- socket.write("Host: #{uri.host}:#{uri.port}\r\n")
81
- socket.write("Transfer-Encoding: chunked\r\n")
82
- socket.write("Content-Type: text/plain\r\n")
83
- socket.write("Connection: close\r\n")
84
- socket.write("X-Output: output.txt\r\n")
85
- socket.write("\r\n")
75
+ describe "when handling POST requests with 'chunked' transfer encoding" do
76
+ before :each do
77
+ @uri = URI.parse(@server)
78
+ end
86
79
 
87
- chunk = "foo=bar!"
88
- socket.write("%X\r\n%s\r\n" % [chunk.size, chunk])
89
- socket.write("0\r\n\r\n")
90
- socket.flush
80
+ it "dechunks the request body for the app" do
81
+ socket = TCPSocket.new(@uri.host, @uri.port)
82
+ begin
83
+ socket.write("POST #{base_uri}/raw_upload_to_file HTTP/1.1\r\n")
84
+ socket.write("Host: #{@uri.host}:#{@uri.port}\r\n")
85
+ socket.write("Transfer-Encoding: chunked\r\n")
86
+ socket.write("Content-Type: text/plain\r\n")
87
+ socket.write("Connection: close\r\n")
88
+ socket.write("X-Output: output.txt\r\n")
89
+ socket.write("\r\n")
91
90
 
92
- socket.read.should =~ /\r\nok\Z/
93
- ensure
94
- socket.close
91
+ chunk = "foo=bar!"
92
+ socket.write("%X\r\n%s\r\n" % [chunk.size, chunk])
93
+ socket.write("0\r\n\r\n")
94
+ socket.flush
95
+
96
+ socket.read.should =~ /\r\nok\Z/
97
+ ensure
98
+ socket.close
99
+ end
100
+
101
+ File.read(@stub.full_app_root + "/output.txt").should == "foo=bar!"
95
102
  end
96
103
 
97
- File.read(@stub.full_app_root + "/output.txt").should == "foo=bar!"
104
+ it "sets Content-Length and removes Transfer-Encoding in the request" do
105
+ socket = TCPSocket.new(@uri.host, @uri.port)
106
+ begin
107
+ socket.write("POST #{base_uri}/env HTTP/1.1\r\n")
108
+ socket.write("Host: #{@uri.host}:#{@uri.port}\r\n")
109
+ socket.write("Transfer-Encoding: chunked\r\n")
110
+ socket.write("Content-Type: text/plain\r\n")
111
+ socket.write("Connection: close\r\n")
112
+ socket.write("\r\n")
113
+
114
+ chunk = "foo=bar!"
115
+ socket.write("%X\r\n%s\r\n" % [chunk.size, chunk])
116
+ socket.write("0\r\n\r\n")
117
+ socket.flush
118
+
119
+ response = socket.read
120
+ response.should include("CONTENT_LENGTH = 8\n")
121
+ response.should_not include("HTTP_TRANSFER_ENCODING = ")
122
+ ensure
123
+ socket.close
124
+ end
125
+ end
98
126
  end
99
127
 
100
128
  it "supports responses with the 'chunked' transfer encoding" do
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.37
4
+ version: 4.0.38
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-01-28 00:00:00.000000000 Z
11
+ date: 2014-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
- version: 1.1.0
33
+ version: 1.2.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
- version: 1.1.0
40
+ version: 1.2.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rack
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -68,11 +68,11 @@ extra_rdoc_files: []
68
68
  files:
69
69
  - .gitignore
70
70
  - .travis.yml
71
+ - CHANGELOG
71
72
  - CONTRIBUTING.md
72
73
  - CONTRIBUTORS
73
74
  - INSTALL.md
74
75
  - LICENSE
75
- - NEWS
76
76
  - README.md
77
77
  - Rakefile
78
78
  - bin/passenger
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
- iQEcBAABAgAGBQJS6CPHAAoJECrHRaUKISqMVE8IAJ1rJonGDQ1UC7Yvb15ee0rP
6
- GfZ/TfGnc/4QhQPiurKmZedvNR8J2jX1rpHDZ608V5x2/ob6XRu4JjWNsfQa9dg2
7
- cj5voVZEVJzEQEPVfqAGxFxWGoAB/Y0sOMV+gm6ApPYVLrx7E+Z9zrA4MPD+Cg21
8
- 3BDA85scuJVJbzE/83m3DfmqcdNnyLga4jXRJ5BoiFgsDmbK672nrKB/1z/rMlK9
9
- JPXtWWAIvMb4W28VSQ9khqAkMkqzn+QoBU0IamaTc9uguktnCdvkMoy8tI2ximYB
10
- Vsl1e3/nNIcGpUhIoe55se9D4d242c4sge0RlFWbnkTnfqCRkos/Sn6l+yn8HkU=
11
- =aUm3
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+
12
12
  -----END PGP SIGNATURE-----