unicorn 5.3.1 → 5.4.0
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 +5 -5
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +5 -0
- data/ISSUES +5 -0
- data/ext/unicorn_http/unicorn_http.rl +15 -0
- data/lib/unicorn.rb +4 -1
- data/lib/unicorn/configurator.rb +1 -1
- data/lib/unicorn/http_request.rb +1 -0
- data/lib/unicorn/http_response.rb +3 -2
- data/lib/unicorn/http_server.rb +2 -3
- data/lib/unicorn/socket_helper.rb +1 -1
- data/t/hijack.ru +12 -0
- data/t/t0200-rack-hijack.sh +22 -1
- data/test/unit/test_droplet.rb +1 -1
- data/test/unit/test_request.rb +10 -10
- data/unicorn.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2a53c6f0287f74563b46ac07e96cbb709562e4f26bdbf46ae1cb904a3e345828
|
4
|
+
data.tar.gz: 0724bceedd3b964168081c4a12c8f9eb04611013f6ef72593d6db63bd31cccf1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0b91ca7dd6cc2e52f7eed8fdd30547dbcd3c81939c1df495e612ff94a544dc589cd3d3cd9e4c17206f135ac7e3ef763ecfa80bebacce42960df7f93a679d091
|
7
|
+
data.tar.gz: 9eba1d1fefa858d93524ff73c77b8a239b9e50abb6f8bac840d436afebd27608dcad6a8d7f49c35dd44f2577563fdbdc898541efa312b7f5953c155cf1eaf057
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -249,5 +249,10 @@ endif
|
|
249
249
|
$(PLACEHOLDERS):
|
250
250
|
echo olddoc_placeholder > $@
|
251
251
|
|
252
|
+
check-warnings:
|
253
|
+
@(for i in $$(git ls-files '*.rb' bin | grep -v '^setup\.rb$$'); \
|
254
|
+
do $(RUBY) --disable-gems -d -W2 -c \
|
255
|
+
$$i; done) | grep -v '^Syntax OK$$' || :
|
256
|
+
|
252
257
|
.PHONY: .FORCE-GIT-VERSION-FILE doc $(T) $(slow_tests) man
|
253
258
|
.PHONY: test-install
|
data/ISSUES
CHANGED
@@ -15,6 +15,11 @@ submit patches and/or obtain support after you have searched the
|
|
15
15
|
* The email submission port (587) is enabled on the bogomips.org MX:
|
16
16
|
https://bogomips.org/unicorn-public/20141004232241.GA23908@dcvr.yhbt.net/t/
|
17
17
|
|
18
|
+
We will never have a centralized or formal bug tracker. Instead we
|
19
|
+
can interoperate with any bug tracker which can Cc: us plain-text to
|
20
|
+
mailto:unicorn-public@bogomips.org This includes the Debian BTS
|
21
|
+
at https://bugs.debian.org/unicorn and possibly others.
|
22
|
+
|
18
23
|
If your issue is of a sensitive nature or you're just shy in public,
|
19
24
|
use anonymity tools such as Tor or Mixmaster; and rely on the public
|
20
25
|
mail archives for responses. Be sure to scrub sensitive log messages
|
@@ -26,6 +26,7 @@ void init_unicorn_httpdate(VALUE mark_ary);
|
|
26
26
|
#define UH_FL_HASHEADER 0x100
|
27
27
|
#define UH_FL_TO_CLEAR 0x200
|
28
28
|
#define UH_FL_RESSTART 0x400 /* for check_client_connection */
|
29
|
+
#define UH_FL_HIJACK 0x800
|
29
30
|
|
30
31
|
/* all of these flags need to be set for keepalive to be supported */
|
31
32
|
#define UH_FL_KEEPALIVE (UH_FL_KAVERSION | UH_FL_REQEOF | UH_FL_HASHEADER)
|
@@ -607,6 +608,10 @@ static VALUE HttpParser_clear(VALUE self)
|
|
607
608
|
{
|
608
609
|
struct http_parser *hp = data_get(self);
|
609
610
|
|
611
|
+
/* we can't safely reuse .buf and .env if hijacked */
|
612
|
+
if (HP_FL_TEST(hp, HIJACK))
|
613
|
+
return HttpParser_init(self);
|
614
|
+
|
610
615
|
http_parser_init(hp);
|
611
616
|
my_hash_clear(hp->env);
|
612
617
|
|
@@ -813,6 +818,15 @@ static VALUE HttpParser_env(VALUE self)
|
|
813
818
|
return data_get(self)->env;
|
814
819
|
}
|
815
820
|
|
821
|
+
static VALUE HttpParser_hijacked_bang(VALUE self)
|
822
|
+
{
|
823
|
+
struct http_parser *hp = data_get(self);
|
824
|
+
|
825
|
+
HP_FL_SET(hp, HIJACK);
|
826
|
+
|
827
|
+
return self;
|
828
|
+
}
|
829
|
+
|
816
830
|
/**
|
817
831
|
* call-seq:
|
818
832
|
* parser.filter_body(dst, src) => nil/src
|
@@ -947,6 +961,7 @@ void Init_unicorn_http(void)
|
|
947
961
|
rb_define_method(cHttpParser, "next?", HttpParser_next, 0);
|
948
962
|
rb_define_method(cHttpParser, "buf", HttpParser_buf, 0);
|
949
963
|
rb_define_method(cHttpParser, "env", HttpParser_env, 0);
|
964
|
+
rb_define_method(cHttpParser, "hijacked!", HttpParser_hijacked_bang, 0);
|
950
965
|
rb_define_method(cHttpParser, "response_start_sent=", HttpParser_rssset, 1);
|
951
966
|
rb_define_method(cHttpParser, "response_start_sent", HttpParser_rssget, 0);
|
952
967
|
|
data/lib/unicorn.rb
CHANGED
@@ -59,7 +59,10 @@ def self.builder(ru, op)
|
|
59
59
|
Object.const_get(File.basename(ru, '.rb').capitalize)
|
60
60
|
end
|
61
61
|
|
62
|
-
|
62
|
+
if $DEBUG
|
63
|
+
require 'pp'
|
64
|
+
pp({ :inner_app => inner_app })
|
65
|
+
end
|
63
66
|
|
64
67
|
return inner_app if no_default_middleware
|
65
68
|
|
data/lib/unicorn/configurator.rb
CHANGED
@@ -587,7 +587,7 @@ def working_directory(path)
|
|
587
587
|
# just let chdir raise errors
|
588
588
|
path = File.expand_path(path)
|
589
589
|
if config_file &&
|
590
|
-
config_file
|
590
|
+
! config_file.start_with?('/') &&
|
591
591
|
! File.readable?("#{path}/#{config_file}")
|
592
592
|
raise ArgumentError,
|
593
593
|
"config_file=#{config_file} would not be accessible in" \
|
data/lib/unicorn/http_request.rb
CHANGED
@@ -21,13 +21,13 @@ def err_response(code, response_start_sent)
|
|
21
21
|
|
22
22
|
# writes the rack_response to socket as an HTTP response
|
23
23
|
def http_response_write(socket, status, headers, body,
|
24
|
-
|
24
|
+
req = Unicorn::HttpRequest.new)
|
25
25
|
hijack = nil
|
26
26
|
|
27
27
|
if headers
|
28
28
|
code = status.to_i
|
29
29
|
msg = STATUS_CODES[code]
|
30
|
-
start = response_start_sent ? ''.freeze : 'HTTP/1.1 '.freeze
|
30
|
+
start = req.response_start_sent ? ''.freeze : 'HTTP/1.1 '.freeze
|
31
31
|
buf = "#{start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
|
32
32
|
"Date: #{httpdate}\r\n" \
|
33
33
|
"Connection: close\r\n"
|
@@ -52,6 +52,7 @@ def http_response_write(socket, status, headers, body,
|
|
52
52
|
end
|
53
53
|
|
54
54
|
if hijack
|
55
|
+
req.hijacked!
|
55
56
|
hijack.call(socket)
|
56
57
|
else
|
57
58
|
body.each { |chunk| socket.write(chunk) }
|
data/lib/unicorn/http_server.rb
CHANGED
@@ -148,7 +148,7 @@ def start
|
|
148
148
|
def listeners=(listeners)
|
149
149
|
cur_names, dead_names = [], []
|
150
150
|
listener_names.each do |name|
|
151
|
-
if
|
151
|
+
if name.start_with?('/')
|
152
152
|
# mark unlinked sockets as dead so we can rebind them
|
153
153
|
(File.socket?(name) ? cur_names : dead_names) << name
|
154
154
|
else
|
@@ -614,8 +614,7 @@ def process_client(client)
|
|
614
614
|
return if @request.hijacked?
|
615
615
|
end
|
616
616
|
@request.headers? or headers = nil
|
617
|
-
http_response_write(client, status, headers, body,
|
618
|
-
@request.response_start_sent)
|
617
|
+
http_response_write(client, status, headers, body, @request)
|
619
618
|
ensure
|
620
619
|
body.respond_to?(:close) and body.close
|
621
620
|
end
|
@@ -116,7 +116,7 @@ def log_buffer_sizes(sock, pfx = '')
|
|
116
116
|
def bind_listen(address = '0.0.0.0:8080', opt = {})
|
117
117
|
return address unless String === address
|
118
118
|
|
119
|
-
sock = if address
|
119
|
+
sock = if address.start_with?('/')
|
120
120
|
if File.exist?(address)
|
121
121
|
if File.socket?(address)
|
122
122
|
begin
|
data/t/hijack.ru
CHANGED
@@ -11,11 +11,15 @@ def close
|
|
11
11
|
warn "closed DieIfUsed #{@@n += 1}\n"
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
envs = []
|
16
|
+
|
14
17
|
run lambda { |env|
|
15
18
|
case env["PATH_INFO"]
|
16
19
|
when "/hijack_req"
|
17
20
|
if env["rack.hijack?"]
|
18
21
|
io = env["rack.hijack"].call
|
22
|
+
envs << env
|
19
23
|
if io.respond_to?(:read_nonblock) &&
|
20
24
|
env["rack.hijack_io"].respond_to?(:read_nonblock)
|
21
25
|
|
@@ -33,11 +37,19 @@ def close
|
|
33
37
|
{
|
34
38
|
"Content-Length" => r.bytesize.to_s,
|
35
39
|
"rack.hijack" => proc do |io|
|
40
|
+
envs << env
|
36
41
|
io.write(r)
|
37
42
|
io.close
|
38
43
|
end
|
39
44
|
},
|
40
45
|
DieIfUsed.new
|
41
46
|
]
|
47
|
+
when "/normal_env_id"
|
48
|
+
b = "#{env.object_id}\n"
|
49
|
+
h = {
|
50
|
+
'Content-Type' => 'text/plain',
|
51
|
+
'Content-Length' => b.bytesize.to_s,
|
52
|
+
}
|
53
|
+
[ 200, h, [ b ] ]
|
42
54
|
end
|
43
55
|
}
|
data/t/t0200-rack-hijack.sh
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
. ./test-lib.sh
|
3
|
-
t_plan
|
3
|
+
t_plan 9 "rack.hijack tests (Rack 1.5+ (Rack::VERSION >= [ 1,2]))"
|
4
4
|
|
5
5
|
t_begin "setup and start" && {
|
6
6
|
unicorn_setup
|
@@ -8,14 +8,35 @@ t_begin "setup and start" && {
|
|
8
8
|
unicorn_wait_start
|
9
9
|
}
|
10
10
|
|
11
|
+
t_begin "normal env reused between requests" && {
|
12
|
+
env_a="$(curl -sSf http://$listen/normal_env_id)"
|
13
|
+
b="$(curl -sSf http://$listen/normal_env_id)"
|
14
|
+
test x"$env_a" = x"$b"
|
15
|
+
}
|
16
|
+
|
11
17
|
t_begin "check request hijack" && {
|
12
18
|
test "xrequest.hijacked" = x"$(curl -sSfv http://$listen/hijack_req)"
|
13
19
|
}
|
14
20
|
|
21
|
+
t_begin "env changed after request hijack" && {
|
22
|
+
env_b="$(curl -sSf http://$listen/normal_env_id)"
|
23
|
+
test x"$env_a" != x"$env_b"
|
24
|
+
}
|
25
|
+
|
15
26
|
t_begin "check response hijack" && {
|
16
27
|
test "xresponse.hijacked" = x"$(curl -sSfv http://$listen/hijack_res)"
|
17
28
|
}
|
18
29
|
|
30
|
+
t_begin "env changed after response hijack" && {
|
31
|
+
env_c="$(curl -sSf http://$listen/normal_env_id)"
|
32
|
+
test x"$env_b" != x"$env_c"
|
33
|
+
}
|
34
|
+
|
35
|
+
t_begin "env continues to be reused between requests" && {
|
36
|
+
b="$(curl -sSf http://$listen/normal_env_id)"
|
37
|
+
test x"$env_c" = x"$b"
|
38
|
+
}
|
39
|
+
|
19
40
|
t_begin "killing succeeds after hijack" && {
|
20
41
|
kill $unicorn_pid
|
21
42
|
}
|
data/test/unit/test_droplet.rb
CHANGED
data/test/unit/test_request.rb
CHANGED
@@ -34,7 +34,7 @@ def test_options
|
|
34
34
|
assert_equal '', env['REQUEST_PATH']
|
35
35
|
assert_equal '', env['PATH_INFO']
|
36
36
|
assert_equal '*', env['REQUEST_URI']
|
37
|
-
|
37
|
+
assert_kind_of Array, @lint.call(env)
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_absolute_uri_with_query
|
@@ -44,7 +44,7 @@ def test_absolute_uri_with_query
|
|
44
44
|
assert_equal '/x', env['REQUEST_PATH']
|
45
45
|
assert_equal '/x', env['PATH_INFO']
|
46
46
|
assert_equal 'y=z', env['QUERY_STRING']
|
47
|
-
|
47
|
+
assert_kind_of Array, @lint.call(env)
|
48
48
|
end
|
49
49
|
|
50
50
|
def test_absolute_uri_with_fragment
|
@@ -55,7 +55,7 @@ def test_absolute_uri_with_fragment
|
|
55
55
|
assert_equal '/x', env['PATH_INFO']
|
56
56
|
assert_equal '', env['QUERY_STRING']
|
57
57
|
assert_equal 'frag', env['FRAGMENT']
|
58
|
-
|
58
|
+
assert_kind_of Array, @lint.call(env)
|
59
59
|
end
|
60
60
|
|
61
61
|
def test_absolute_uri_with_query_and_fragment
|
@@ -66,7 +66,7 @@ def test_absolute_uri_with_query_and_fragment
|
|
66
66
|
assert_equal '/x', env['PATH_INFO']
|
67
67
|
assert_equal 'a=b', env['QUERY_STRING']
|
68
68
|
assert_equal 'frag', env['FRAGMENT']
|
69
|
-
|
69
|
+
assert_kind_of Array, @lint.call(env)
|
70
70
|
end
|
71
71
|
|
72
72
|
def test_absolute_uri_unsupported_schemes
|
@@ -83,7 +83,7 @@ def test_x_forwarded_proto_https
|
|
83
83
|
"Host: foo\r\n\r\n")
|
84
84
|
env = @request.read(client)
|
85
85
|
assert_equal "https", env['rack.url_scheme']
|
86
|
-
|
86
|
+
assert_kind_of Array, @lint.call(env)
|
87
87
|
end
|
88
88
|
|
89
89
|
def test_x_forwarded_proto_http
|
@@ -92,7 +92,7 @@ def test_x_forwarded_proto_http
|
|
92
92
|
"Host: foo\r\n\r\n")
|
93
93
|
env = @request.read(client)
|
94
94
|
assert_equal "http", env['rack.url_scheme']
|
95
|
-
|
95
|
+
assert_kind_of Array, @lint.call(env)
|
96
96
|
end
|
97
97
|
|
98
98
|
def test_x_forwarded_proto_invalid
|
@@ -101,7 +101,7 @@ def test_x_forwarded_proto_invalid
|
|
101
101
|
"Host: foo\r\n\r\n")
|
102
102
|
env = @request.read(client)
|
103
103
|
assert_equal "http", env['rack.url_scheme']
|
104
|
-
|
104
|
+
assert_kind_of Array, @lint.call(env)
|
105
105
|
end
|
106
106
|
|
107
107
|
def test_rack_lint_get
|
@@ -109,7 +109,7 @@ def test_rack_lint_get
|
|
109
109
|
env = @request.read(client)
|
110
110
|
assert_equal "http", env['rack.url_scheme']
|
111
111
|
assert_equal '127.0.0.1', env['REMOTE_ADDR']
|
112
|
-
|
112
|
+
assert_kind_of Array, @lint.call(env)
|
113
113
|
end
|
114
114
|
|
115
115
|
def test_no_content_stringio
|
@@ -143,7 +143,7 @@ def test_rack_lint_put
|
|
143
143
|
"abcde")
|
144
144
|
env = @request.read(client)
|
145
145
|
assert ! env.include?(:http_body)
|
146
|
-
|
146
|
+
assert_kind_of Array, @lint.call(env)
|
147
147
|
end
|
148
148
|
|
149
149
|
def test_rack_lint_big_put
|
@@ -177,6 +177,6 @@ def client.kgio_read!(*args)
|
|
177
177
|
}
|
178
178
|
assert_nil env['rack.input'].read(bs)
|
179
179
|
env['rack.input'].rewind
|
180
|
-
|
180
|
+
assert_kind_of Array, @lint.call(env)
|
181
181
|
end
|
182
182
|
end
|
data/unicorn.gemspec
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
|
12
12
|
Gem::Specification.new do |s|
|
13
13
|
s.name = %q{unicorn}
|
14
|
-
s.version = (ENV['VERSION'] || '5.
|
14
|
+
s.version = (ENV['VERSION'] || '5.4.0').dup
|
15
15
|
s.authors = ['unicorn hackers']
|
16
16
|
s.summary = 'Rack HTTP server for fast clients and Unix'
|
17
17
|
s.description = File.read('README').split("\n\n")[1]
|
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.
|
4
|
+
version: 5.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- unicorn hackers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -288,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
288
|
version: '0'
|
289
289
|
requirements: []
|
290
290
|
rubyforge_project:
|
291
|
-
rubygems_version: 2.
|
291
|
+
rubygems_version: 2.7.3
|
292
292
|
signing_key:
|
293
293
|
specification_version: 4
|
294
294
|
summary: Rack HTTP server for fast clients and Unix
|