unicorn 5.3.1 → 5.4.0

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
- SHA1:
3
- metadata.gz: cae827cc4674fdbfd9291caf3037f0fe4a5e67b7
4
- data.tar.gz: e6518f02407def59575f3efb01a54019e0fdcab9
2
+ SHA256:
3
+ metadata.gz: 2a53c6f0287f74563b46ac07e96cbb709562e4f26bdbf46ae1cb904a3e345828
4
+ data.tar.gz: 0724bceedd3b964168081c4a12c8f9eb04611013f6ef72593d6db63bd31cccf1
5
5
  SHA512:
6
- metadata.gz: 2a9bd5f4dacb2aa56002b9899d1725bdfc124def5b9287ff464b3ed0e47785db1aa14b52757173d990972ad5a3a4afc44e37f052f7ef8ac92ae7fac0daa3645d
7
- data.tar.gz: da9be558581cb34ee8b8c81bdcfcd659dc5e26d0cc42aa291ced5749ea07cbfe14fdce7a2fbfd43339990331e9c58e346d0129ea035c817ff59c8825d34f5645
6
+ metadata.gz: a0b91ca7dd6cc2e52f7eed8fdd30547dbcd3c81939c1df495e612ff94a544dc589cd3d3cd9e4c17206f135ac7e3ef763ecfa80bebacce42960df7f93a679d091
7
+ data.tar.gz: 9eba1d1fefa858d93524ff73c77b8a239b9e50abb6f8bac840d436afebd27608dcad6a8d7f49c35dd44f2577563fdbdc898541efa312b7f5953c155cf1eaf057
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- DEF_VER = "v5.3.1"
2
+ DEF_VER = "v5.4.0"
3
3
  CONSTANT = "Unicorn::Const::UNICORN_VERSION"
4
4
  RVF = "lib/unicorn/version.rb"
5
5
  GVF = "GIT-VERSION-FILE"
@@ -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
 
@@ -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
- pp({ :inner_app => inner_app }) if $DEBUG
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
 
@@ -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[0] != ?/ &&
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" \
@@ -98,6 +98,7 @@ def read(socket)
98
98
  # for rack.hijack, we respond to this method so no extra allocation
99
99
  # of a proc object
100
100
  def call
101
+ hijacked!
101
102
  env['rack.hijack_io'] = env['unicorn.socket']
102
103
  end
103
104
 
@@ -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
- response_start_sent=false)
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) }
@@ -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 ?/ == name[0]
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[0] == ?/
119
+ sock = if address.start_with?('/')
120
120
  if File.exist?(address)
121
121
  if File.socket?(address)
122
122
  begin
@@ -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
  }
@@ -1,6 +1,6 @@
1
1
  #!/bin/sh
2
2
  . ./test-lib.sh
3
- t_plan 5 "rack.hijack tests (Rack 1.5+ (Rack::VERSION >= [ 1,2]))"
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
  }
@@ -4,7 +4,7 @@
4
4
  class TestDroplet < Test::Unit::TestCase
5
5
  def test_create_many_droplets
6
6
  now = Time.now.to_i
7
- tmp = (0..1024).map do |i|
7
+ (0..1024).each do |i|
8
8
  droplet = Unicorn::Worker.new(i)
9
9
  assert droplet.respond_to?(:tick)
10
10
  assert_equal 0, droplet.tick
@@ -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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
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
- res = @lint.call(env)
180
+ assert_kind_of Array, @lint.call(env)
181
181
  end
182
182
  end
@@ -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.3.1').dup
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.3.1
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-10-03 00:00:00.000000000 Z
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.6.13
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