unicorn 5.0.0.pre1 → 5.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d5848d63c8d3b1acc91d0369e8fb48cb5ca3b984
4
- data.tar.gz: e48d019bec3a78fcf9cd08837c2b0834d1bb0a79
3
+ metadata.gz: b6c852e81779e85bb954acba25ddca3052c49a37
4
+ data.tar.gz: 18988f20b63a361f2c606852dfb120727cafddbf
5
5
  SHA512:
6
- metadata.gz: 2fc2d66e37047978875cdd7fbaf656059887c441252b873ad4b0f182d72d891aa8947279837058b1d723e032a9a42d41d6b519d22211702121e6c3d3b217fe6d
7
- data.tar.gz: 04c4d2d9313741970170eb8c7b68f9ff5bd63c6523d077a339aa58446700a879847b5169604f75ada80c9ead847ae409a796c059e9ab0c68722786c798f5ae28
6
+ metadata.gz: f8fec82ab6107eabaf3454b2769ea1f9e27bdbf2df8e04b5ca9931bb29bdf86fda850ecb8557b981288571cb45476fe59d9519fb1b9d4863267b2bcd0534fc3e
7
+ data.tar.gz: 3644b70f5c195f3ca9c1816c4b5f1dbcd153383f9b4bc60ce3a3cafdc5b2435d348ddcf88d4f75b3e4016d80326882ce7b794d1cc8c2712af9f8c5a0575bc77e
@@ -180,6 +180,6 @@ startup, otherwise the socket will be closed.
180
180
  * [Rackup HowTo][3]
181
181
 
182
182
  [1]: http://unicorn.bogomips.org/
183
- [2]: http://rdoc.info/gems/r#/gems/rack/frames
184
- [3]: http://wiki.github.com/rack/rack/tutorial-rackup-howto
183
+ [2]: http://www.rubydoc.info/github/rack/rack/
184
+ [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
185
185
  [4]: http://unicorn.bogomips.org/SIGNALS.html
@@ -170,6 +170,6 @@ used by Unicorn.
170
170
  * [Rackup HowTo][3]
171
171
 
172
172
  [1]: http://unicorn.bogomips.org/
173
- [2]: http://rdoc.info/gems/r#/gems/rack/frames
174
- [3]: http://wiki.github.com/rack/rack/tutorial-rackup-howto
173
+ [2]: http://www.rubydoc.info/github/rack/rack/
174
+ [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
175
175
  [4]: http://unicorn.bogomips.org/SIGNALS.html
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- DEF_VER = "v5.0.0.pre1"
2
+ DEF_VER = "v5.0.0.pre2"
3
3
  CONSTANT = "Unicorn::Const::UNICORN_VERSION"
4
4
  RVF = "lib/unicorn/version.rb"
5
5
  GVF = "GIT-VERSION-FILE"
@@ -38,7 +38,7 @@ acceptable solution. Those issues are documented here.
38
38
  after_fork hook to get correct random number generation. We have a builtin
39
39
  workaround for this starting with \Unicorn 3.6.1
40
40
 
41
- See http://redmine.ruby-lang.org/issues/show/4338
41
+ See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/36450
42
42
 
43
43
  * On Ruby 1.8 prior to Ruby 1.8.7-p248, *BSD platforms have a broken
44
44
  stdio that causes failure for file uploads larger than 112K. Upgrade
@@ -49,7 +49,7 @@ acceptable solution. Those issues are documented here.
49
49
  "Kernel.rand" in your after_fork hook to reinitialize the random
50
50
  number generator.
51
51
 
52
- See http://redmine.ruby-lang.org/issues/show/2962 for more details
52
+ See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/28655
53
53
 
54
54
  * Rails 2.3.2 bundles its own version of Rack. This may cause subtle
55
55
  bugs when simultaneously loaded with the system-wide Rack Rubygem
data/Links CHANGED
@@ -34,7 +34,8 @@ or services behind them.
34
34
  * {Rack}[http://rack.github.io/] - a minimal interface between webservers
35
35
  supporting Ruby and Ruby frameworks
36
36
 
37
- * {Ruby}[http://www.ruby-lang.org/] - the programming language of Rack and \Unicorn
37
+ * {Ruby}[https://www.ruby-lang.org/en/] - the programming language of
38
+ Rack and \Unicorn
38
39
 
39
40
  * {nginx}[http://nginx.org/] - the reverse proxy for use with \Unicorn
40
41
 
data/README CHANGED
@@ -10,7 +10,7 @@ both the the request and response in between \Unicorn and slow clients.
10
10
 
11
11
  * Designed for Rack, Unix, fast clients, and ease-of-debugging. We
12
12
  cut out everything that is better supported by the operating system,
13
- {nginx}[http://nginx.net/] or {Rack}[http://rack.github.io/].
13
+ {nginx}[http://nginx.org/] or {Rack}[http://rack.github.io/].
14
14
 
15
15
  * Compatible with Ruby 1.9.3 and later.
16
16
  unicorn 4.8.x will remain supported for Ruby 1.8 users.
data/SIGNALS CHANGED
@@ -3,7 +3,7 @@
3
3
  In general, signals need only be sent to the master process. However,
4
4
  the signals Unicorn uses internally to communicate with the worker
5
5
  processes are documented here as well. With the exception of TTIN/TTOU,
6
- signal handling matches the behavior of {nginx}[http://nginx.net/] so it
6
+ signal handling matches the behavior of {nginx}[http://nginx.org/] so it
7
7
  should be possible to easily share process management scripts between
8
8
  Unicorn and nginx.
9
9
 
data/Sandbox CHANGED
@@ -3,8 +3,8 @@
3
3
  Since unicorn includes executables and is usually used to start a Ruby
4
4
  process, there are certain caveats to using it with tools that sandbox
5
5
  RubyGems installations such as
6
- {Bundler}[http://gembundler.com/] or
7
- {Isolate}[http://github.com/jbarnette/isolate].
6
+ {Bundler}[http://bundler.io/] or
7
+ {Isolate}[https://github.com/jbarnette/isolate].
8
8
 
9
9
  == General deployment
10
10
 
@@ -58,7 +58,7 @@ the before_exec hook:
58
58
 
59
59
  If you're using an older Bundler version (0.9.x), you may need to set or
60
60
  reset GEM_HOME, GEM_PATH and PATH environment variables in the
61
- before_exec hook as illustrated by http://gist.github.com/534668
61
+ before_exec hook as illustrated by https://gist.github.com/534668
62
62
 
63
63
  === Ruby 2.0.0 close-on-exec and SIGUSR2 incompatibility
64
64
 
@@ -21,17 +21,12 @@ class Unicorn::HttpParser
21
21
  "SERVER_SOFTWARE" => "Unicorn #{Unicorn::Const::UNICORN_VERSION}"
22
22
  }
23
23
 
24
- RACK_HIJACK = "rack.hijack".freeze
25
- RACK_HIJACK_IO = "rack.hijack_io".freeze
26
24
  NULL_IO = StringIO.new("")
27
25
 
28
26
  # :stopdoc:
29
27
  # A frozen format for this is about 15% faster
30
28
  # Drop these frozen strings when Ruby 2.2 becomes more prevalent,
31
29
  # 2.2+ optimizes hash assignments when used with literal string keys
32
- REMOTE_ADDR = 'REMOTE_ADDR'.freeze
33
- RACK_INPUT = 'rack.input'.freeze
34
- UNICORN_SOCKET = 'unicorn.socket'.freeze
35
30
  HTTP_RESPONSE_START = [ 'HTTP', '/1.1 ']
36
31
  @@input_class = Unicorn::TeeInput
37
32
  @@check_client_connection = false
@@ -78,7 +73,7 @@ class Unicorn::HttpParser
78
73
  # identify the client for the immediate request to the server;
79
74
  # that client may be a proxy, gateway, or other intermediary
80
75
  # acting on behalf of the actual source client."
81
- e[REMOTE_ADDR] = socket.kgio_addr
76
+ e['REMOTE_ADDR'] = socket.kgio_addr
82
77
 
83
78
  # short circuit the common case with small GET requests first
84
79
  socket.kgio_read!(16384, buf)
@@ -94,12 +89,12 @@ class Unicorn::HttpParser
94
89
  HTTP_RESPONSE_START.each { |c| socket.write(c) }
95
90
  end
96
91
 
97
- e[RACK_INPUT] = 0 == content_length ?
98
- NULL_IO : @@input_class.new(socket, self)
92
+ e['rack.input'] = 0 == content_length ?
93
+ NULL_IO : @@input_class.new(socket, self)
99
94
 
100
95
  # for Rack hijacking in Rack 1.5 and later
101
- e[UNICORN_SOCKET] = socket
102
- e[RACK_HIJACK] = self
96
+ e['unicorn.socket'] = socket
97
+ e['rack.hijack'] = self
103
98
 
104
99
  e.merge!(DEFAULTS)
105
100
  end
@@ -107,10 +102,10 @@ class Unicorn::HttpParser
107
102
  # for rack.hijack, we respond to this method so no extra allocation
108
103
  # of a proc object
109
104
  def call
110
- env[RACK_HIJACK_IO] = env[UNICORN_SOCKET]
105
+ env['rack.hijack_io'] = env['unicorn.socket']
111
106
  end
112
107
 
113
108
  def hijacked?
114
- env.include?(RACK_HIJACK_IO)
109
+ env.include?('rack.hijack_io'.freeze)
115
110
  end
116
111
  end
@@ -10,15 +10,10 @@
10
10
  # is the job of Rack, with the exception of the "Date" and "Status" header.
11
11
  module Unicorn::HttpResponse
12
12
 
13
- # Every standard HTTP code mapped to the appropriate message.
14
- CODES = Rack::Utils::HTTP_STATUS_CODES.inject({}) { |hash,(code,msg)|
15
- hash[code] = "#{code} #{msg}"
16
- hash
17
- }
18
- CRLF = "\r\n"
19
-
13
+ # internal API, code will always be common-enough-for-even-old-Rack
20
14
  def err_response(code, response_start_sent)
21
- "#{response_start_sent ? '' : 'HTTP/1.1 '}#{CODES[code]}\r\n\r\n"
15
+ "#{response_start_sent ? '' : 'HTTP/1.1 '}" \
16
+ "#{code} #{Rack::Utils::HTTP_STATUS_CODES[code]}\r\n\r\n"
22
17
  end
23
18
 
24
19
  # writes the rack_response to socket as an HTTP response
@@ -26,9 +21,11 @@ module Unicorn::HttpResponse
26
21
  response_start_sent=false)
27
22
  hijack = nil
28
23
 
29
- http_response_start = response_start_sent ? '' : 'HTTP/1.1 '
30
24
  if headers
31
- buf = "#{http_response_start}#{CODES[status.to_i] || status}\r\n" \
25
+ code = status.to_i
26
+ msg = Rack::Utils::HTTP_STATUS_CODES[code]
27
+ start = response_start_sent ? ''.freeze : 'HTTP/1.1 '.freeze
28
+ buf = "#{start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
32
29
  "Date: #{httpdate}\r\n" \
33
30
  "Connection: close\r\n"
34
31
  headers.each do |key, value|
@@ -40,15 +37,15 @@ module Unicorn::HttpResponse
40
37
  # key in Rack < 1.5
41
38
  hijack = value
42
39
  else
43
- if value =~ /\n/
40
+ if value.include?("\n".freeze)
44
41
  # avoiding blank, key-only cookies with /\n+/
45
- buf << value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" }.join
42
+ value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
46
43
  else
47
44
  buf << "#{key}: #{value}\r\n"
48
45
  end
49
46
  end
50
47
  end
51
- socket.write(buf << CRLF)
48
+ socket.write(buf << "\r\n".freeze)
52
49
  end
53
50
 
54
51
  if hijack
@@ -486,7 +486,8 @@ class Unicorn::HttpServer
486
486
  Unicorn::Configurator::RACKUP.clear
487
487
  @ready_pipe = @init_listeners = @before_exec = @before_fork = nil
488
488
 
489
- srand # http://redmine.ruby-lang.org/issues/4338
489
+ # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/36450
490
+ srand # remove in unicorn 6
490
491
 
491
492
  # The OpenSSL PRNG is seeded with only the pid, and apps with frequently
492
493
  # dying workers can recycle pids
@@ -765,12 +766,23 @@ class Unicorn::HttpServer
765
766
  def inherit_listeners!
766
767
  # inherit sockets from parents, they need to be plain Socket objects
767
768
  # before they become Kgio::UNIXServer or Kgio::TCPServer
768
- inherited = ENV['UNICORN_FD'].to_s.split(',').map do |fd|
769
- io = Socket.for_fd(fd.to_i)
770
- set_server_sockopt(io, listener_opts[sock_name(io)])
769
+ inherited = ENV['UNICORN_FD'].to_s.split(',')
770
+
771
+ # emulate sd_listen_fds() for systemd
772
+ sd_pid, sd_fds = ENV.values_at('LISTEN_PID', 'LISTEN_FDS')
773
+ if sd_pid && sd_pid.to_i == $$
774
+ # 3 = SD_LISTEN_FDS_START
775
+ inherited.concat((3...(3 + sd_fds.to_i)).map { |fd| Socket.for_fd(fd) })
776
+ end
777
+ # to ease debugging, we will not unset LISTEN_PID and LISTEN_FDS
778
+
779
+ inherited.map! do |fd|
780
+ io = String === fd ? Socket.for_fd(fd.to_i) : fd
771
781
  io.autoclose = false
772
- logger.info "inherited addr=#{sock_name(io)} fd=#{fd}"
773
- server_cast(io)
782
+ io = server_cast(io)
783
+ set_server_sockopt(io, listener_opts[sock_name(io)])
784
+ logger.info "inherited addr=#{sock_name(io)} fd=#{io.fileno}"
785
+ io
774
786
  end
775
787
 
776
788
  config_listeners = config[:listeners].dup
@@ -96,6 +96,30 @@ run lambda { |env|
96
96
  end
97
97
  end
98
98
 
99
+ def test_sd_listen_fds_emulation
100
+ File.open("config.ru", "wb") { |fp| fp.write(HI) }
101
+ sock = TCPServer.new(@addr, @port)
102
+ sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 0)
103
+
104
+ pid = xfork do
105
+ redirect_test_io do
106
+ # pretend to be systemd
107
+ ENV['LISTEN_PID'] = "#$$"
108
+ ENV['LISTEN_FDS'] = '1'
109
+
110
+ # 3 = SD_LISTEN_FDS_START
111
+ exec($unicorn_bin, "-l", "#@addr:#@port", 3 => sock)
112
+ end
113
+ end
114
+ res = hit(["http://#{@addr}:#{@port}/"])
115
+ assert_equal [ "HI\n"], res
116
+ assert_shutdown(pid)
117
+ assert_equal 1, sock.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).int,
118
+ "unicorn should always set SO_KEEPALIVE on inherited sockets"
119
+ ensure
120
+ sock.close if sock
121
+ end
122
+
99
123
  def test_working_directory_rel_path_config_file
100
124
  other = Tempfile.new('unicorn.wd')
101
125
  File.unlink(other.path)
@@ -79,4 +79,24 @@ class ResponseTest < Test::Unit::TestCase
79
79
  headers = out.string.split(/\r\n\r\n/).first.split(/\r\n/)
80
80
  assert %r{\AHTTP/\d\.\d 666 I AM THE BEAST\z}.match(headers[0])
81
81
  end
82
+
83
+ def test_modified_rack_http_status_codes_late
84
+ r, w = IO.pipe
85
+ pid = fork do
86
+ r.close
87
+ # Users may want to globally override the status text associated
88
+ # with an HTTP status code in their app.
89
+ Rack::Utils::HTTP_STATUS_CODES[200] = "HI"
90
+ http_response_write(w, 200, {}, [])
91
+ w.close
92
+ end
93
+ w.close
94
+ assert_equal "HTTP/1.1 200 HI\r\n", r.gets
95
+ r.read # just drain the pipe
96
+ pid, status = Process.waitpid2(pid)
97
+ assert status.success?, status.inspect
98
+ ensure
99
+ r.close
100
+ w.close unless w.closed?
101
+ end
82
102
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.pre1
4
+ version: 5.0.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Unicorn hackers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-15 00:00:00.000000000 Z
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -298,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
298
298
  version: 1.3.1
299
299
  requirements: []
300
300
  rubyforge_project:
301
- rubygems_version: 2.4.5
301
+ rubygems_version: 2.4.8
302
302
  signing_key:
303
303
  specification_version: 4
304
304
  summary: Rack HTTP server for fast clients and Unix
@@ -307,6 +307,5 @@ test_files:
307
307
  - test/unit/test_http_parser.rb
308
308
  - test/unit/test_http_parser_ng.rb
309
309
  - test/unit/test_request.rb
310
- - test/unit/test_response.rb
311
310
  - test/unit/test_server.rb
312
311
  - test/unit/test_util.rb