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 +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
|