unicorn 5.0.0.pre1 → 5.0.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Documentation/unicorn.1.txt +2 -2
- data/Documentation/unicorn_rails.1.txt +2 -2
- data/GIT-VERSION-GEN +1 -1
- data/KNOWN_ISSUES +2 -2
- data/Links +2 -1
- data/README +1 -1
- data/SIGNALS +1 -1
- data/Sandbox +3 -3
- data/lib/unicorn/http_request.rb +7 -12
- data/lib/unicorn/http_response.rb +10 -13
- data/lib/unicorn/http_server.rb +18 -6
- data/test/exec/test_exec.rb +24 -0
- data/test/unit/test_response.rb +20 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6c852e81779e85bb954acba25ddca3052c49a37
|
4
|
+
data.tar.gz: 18988f20b63a361f2c606852dfb120727cafddbf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8fec82ab6107eabaf3454b2769ea1f9e27bdbf2df8e04b5ca9931bb29bdf86fda850ecb8557b981288571cb45476fe59d9519fb1b9d4863267b2bcd0534fc3e
|
7
|
+
data.tar.gz: 3644b70f5c195f3ca9c1816c4b5f1dbcd153383f9b4bc60ce3a3cafdc5b2435d348ddcf88d4f75b3e4016d80326882ce7b794d1cc8c2712af9f8c5a0575bc77e
|
data/Documentation/unicorn.1.txt
CHANGED
@@ -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://
|
184
|
-
[3]:
|
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://
|
174
|
-
[3]:
|
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
|
data/GIT-VERSION-GEN
CHANGED
data/KNOWN_ISSUES
CHANGED
@@ -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://
|
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://
|
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}[
|
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.
|
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.
|
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://
|
7
|
-
{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
|
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
|
|
data/lib/unicorn/http_request.rb
CHANGED
@@ -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[
|
98
|
-
|
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[
|
102
|
-
e[
|
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[
|
105
|
+
env['rack.hijack_io'] = env['unicorn.socket']
|
111
106
|
end
|
112
107
|
|
113
108
|
def hijacked?
|
114
|
-
env.include?(
|
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
|
-
#
|
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 '}
|
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
|
-
|
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
|
40
|
+
if value.include?("\n".freeze)
|
44
41
|
# avoiding blank, key-only cookies with /\n+/
|
45
|
-
|
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 <<
|
48
|
+
socket.write(buf << "\r\n".freeze)
|
52
49
|
end
|
53
50
|
|
54
51
|
if hijack
|
data/lib/unicorn/http_server.rb
CHANGED
@@ -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
|
-
|
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(',')
|
769
|
-
|
770
|
-
|
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
|
-
|
773
|
-
|
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
|
data/test/exec/test_exec.rb
CHANGED
@@ -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)
|
data/test/unit/test_response.rb
CHANGED
@@ -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.
|
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
|
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.
|
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
|