yahns 1.14.0 → 1.14.1

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: 73a1df35604f8a2a57198e315bc7a3f1c0f008d2
4
- data.tar.gz: 7ad6f6bf6464151fcb205a774e68475549f1a73b
3
+ metadata.gz: 100f23910c77a7e45fdb98c841bf13a166eb0b63
4
+ data.tar.gz: ea3c7b2801fa134773bc079f637ccf419b5e6ef5
5
5
  SHA512:
6
- metadata.gz: 2cc36eff407f38c2fe1d768e334455f311672dd0e82f1376fce79151ef4ec07fe1019646087eb24a1d0cb01d5b792cf40da6eb9ac295d58b9e4bb28e9ecb6e99
7
- data.tar.gz: 8b28720a5ff4234b702347cef2e2cc7e5309886ef6b021ef1592cf2d9363c53235209def345329df1903859697f69b4c3afaafa8f946318c708cc8bd34fd205a
6
+ metadata.gz: 7ee178fa9b9b1122a4446353ca6c6f4744aa1589679deef510fe3afeae40f72f66b8ccb96b56476e2e67383b6cd17f10f23c1fedfd81ab588056944e5693fb83
7
+ data.tar.gz: 1f7a89edf6427deeb0f01b26461c744fa56dc22edc5f84d14eacfb48a50618a5622dcc28e67041843d1ff5de2d6b40c4144b580f044e8770f1e453e268ab10a0
data/GIT-VERSION-GEN CHANGED
@@ -5,7 +5,7 @@
5
5
  CONSTANT = "Yahns::VERSION"
6
6
  RVF = "lib/yahns/version.rb"
7
7
  GVF = "GIT-VERSION-FILE"
8
- DEF_VER = "v1.14.0"
8
+ DEF_VER = "v1.14.1"
9
9
  vn = DEF_VER.dup
10
10
 
11
11
  # First see if there is a version file (included in release tarballs),
@@ -131,68 +131,66 @@ def http_response_write(res, opt)
131
131
  term = false
132
132
  hdr_only, chunk_ok = opt
133
133
 
134
- if @hs.headers?
135
- code = status.to_i
136
- hdr_only ||= Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(code)
137
- msg = Rack::Utils::HTTP_STATUS_CODES[code]
138
- buf = "#{response_start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
139
- "Date: #{httpdate}\r\n".dup
140
- headers.each do |key, value|
141
- case key
142
- when %r{\ADate\z}i
143
- next
144
- when %r{\AContent-Range\z}i
145
- if %r{\Abytes (\d+)-(\d+)/\d+\z} =~ value
146
- offset = $1.to_i
147
- count = $2.to_i - offset + 1
148
- end
149
- kv_str(buf, key, value)
150
- when %r{\AConnection\z}i
151
- # allow Rack apps to tell us they want to drop the client
152
- alive = false if value =~ /\bclose\b/i
153
- when %r{\AContent-Length\z}i
154
- term = true
155
- clen = value.to_i
156
- flags |= MSG_MORE if clen > 0 && !hdr_only
157
- kv_str(buf, key, value)
158
- when %r{\ATransfer-Encoding\z}i
159
- term = true if value =~ /\bchunked\b/i
160
- kv_str(buf, key, value)
161
- when "rack.hijack"
162
- hijack = value
163
- else
164
- kv_str(buf, key, value)
134
+ code = status.to_i
135
+ hdr_only ||= Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(code)
136
+ msg = Rack::Utils::HTTP_STATUS_CODES[code]
137
+ buf = "#{response_start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
138
+ "Date: #{httpdate}\r\n".dup
139
+ headers.each do |key, value|
140
+ case key
141
+ when %r{\ADate\z}i
142
+ next
143
+ when %r{\AContent-Range\z}i
144
+ if %r{\Abytes (\d+)-(\d+)/\d+\z} =~ value
145
+ offset = $1.to_i
146
+ count = $2.to_i - offset + 1
165
147
  end
166
- end
167
- count ||= clen
168
-
169
- if !term && chunk_ok
148
+ kv_str(buf, key, value)
149
+ when %r{\AConnection\z}i
150
+ # allow Rack apps to tell us they want to drop the client
151
+ alive = false if value =~ /\bclose\b/i
152
+ when %r{\AContent-Length\z}i
170
153
  term = true
171
- body = Yahns::ChunkBody.new(body, opt)
172
- buf << "Transfer-Encoding: chunked\r\n".freeze
154
+ clen = value.to_i
155
+ flags |= MSG_MORE if clen > 0 && !hdr_only
156
+ kv_str(buf, key, value)
157
+ when %r{\ATransfer-Encoding\z}i
158
+ term = true if value =~ /\bchunked\b/i
159
+ kv_str(buf, key, value)
160
+ when "rack.hijack"
161
+ hijack = value
162
+ else
163
+ kv_str(buf, key, value)
173
164
  end
174
- alive &&= term
175
- buf << (alive ? "Connection: keep-alive\r\n\r\n".freeze
176
- : "Connection: close\r\n\r\n".freeze)
177
- case rv = kgio_syssend(buf, flags)
178
- when nil # all done, likely
179
- buf.clear
180
- buf = nil # recycle any memory we used ASAP
181
- break
182
- when String
183
- flags = MSG_DONTWAIT
184
- buf = rv # unlikely, hope the skb grows
185
- when :wait_writable, :wait_readable # unlikely
186
- if self.class.output_buffering
187
- alive = hijack ? hijack : alive
188
- rv = response_header_blocked(buf, body, alive, offset, count)
189
- body = nil # ensure we do not close body in ensure
190
- return rv
191
- else
192
- response_wait_write(rv) or return :close
193
- end
194
- end while true
195
165
  end
166
+ count ||= clen
167
+
168
+ if !term && chunk_ok && !hdr_only
169
+ term = true
170
+ body = Yahns::ChunkBody.new(body, opt)
171
+ buf << "Transfer-Encoding: chunked\r\n".freeze
172
+ end
173
+ alive &&= (term || hdr_only)
174
+ buf << (alive ? "Connection: keep-alive\r\n\r\n".freeze
175
+ : "Connection: close\r\n\r\n".freeze)
176
+ case rv = kgio_syssend(buf, flags)
177
+ when nil # all done, likely
178
+ buf.clear
179
+ buf = nil # recycle any memory we used ASAP
180
+ break
181
+ when String
182
+ flags = MSG_DONTWAIT
183
+ buf = rv # unlikely, hope the skb grows
184
+ when :wait_writable, :wait_readable # unlikely
185
+ if self.class.output_buffering
186
+ alive = hijack ? hijack : alive
187
+ rv = response_header_blocked(buf, body, alive, offset, count)
188
+ body = nil # ensure we do not close body in ensure
189
+ return rv
190
+ else
191
+ response_wait_write(rv) or return :close
192
+ end
193
+ end while @hs.headers?
196
194
 
197
195
  return response_hijacked(hijack) if hijack
198
196
  return http_response_done(alive) if hdr_only
@@ -120,7 +120,7 @@ def proxy_res_headers(res, req_res)
120
120
 
121
121
  # chunk the response ourselves if the client supports it,
122
122
  # but the backend does not terminate properly
123
- if alive && ! term
123
+ if alive && ! term && have_body
124
124
  if env['HTTP_VERSION'] == 'HTTP/1.1'.freeze
125
125
  res << "Transfer-Encoding: chunked\r\n".freeze
126
126
  else # we can't persist HTTP/1.0 and HTTP/0.9 w/o Content-Length
@@ -38,7 +38,7 @@ def thr_init
38
38
  Thread.current[:yahns_queue] = self
39
39
  end
40
40
 
41
- # returns an array of infinitely running threads
41
+ # returns an infinitely running thread
42
42
  def worker_thread(logger, max_events)
43
43
  Thread.new do
44
44
  thr_init
@@ -47,7 +47,7 @@ def thr_init
47
47
  Thread.current[:yahns_queue] = self
48
48
  end
49
49
 
50
- # returns an array of infinitely running threads
50
+ # returns an infinitely running thread
51
51
  def worker_thread(logger, max_events)
52
52
  Thread.new do
53
53
  thr_init
@@ -18,7 +18,12 @@ def test_auto_head
18
18
  app = Rack::Builder.new do
19
19
  use Rack::ContentType, "text/plain"
20
20
  run(lambda do |env|
21
- [ 200, {}, %w(a b c) ]
21
+ case env['PATH_INFO']
22
+ when '/204'
23
+ [ 204, {}, [] ]
24
+ else
25
+ [ 200, {}, %w(a b c) ]
26
+ end
22
27
  end)
23
28
  end
24
29
  app(:rack, app) { listen "#{host}:#{port}" }
@@ -50,6 +55,21 @@ def test_auto_head
50
55
  assert_equal 200, res.code.to_i
51
56
  assert_equal 'abc', res.body
52
57
  end
58
+
59
+ s = TCPSocket.new(host, port)
60
+ s.write("GET /204 HTTP/1.1\r\nHost: example.com\r\n\r\n")
61
+ buf = s.readpartial(1024)
62
+ assert_match %r{\r\n\r\n\z}, buf
63
+ refute_match %r{^Transfer-Encoding}i, buf
64
+ assert_match %r{^Connection: keep-alive\r\n}, buf
65
+ assert_nil IO.select([s], nil, nil, 1), 'connection persists..'
66
+
67
+ # maek sure another on the same connection works
68
+ s.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
69
+ buf = s.readpartial(1024)
70
+ assert_match %r{\AHTTP/1\.1 200}, buf
71
+ assert_match(%r{^Transfer-Encoding: chunked\r\n}, buf)
72
+ s.close
53
73
  ensure
54
74
  quit_wait(pid)
55
75
  end
@@ -154,6 +154,9 @@ def chunky.each
154
154
  env['rack.hijack'].call.close
155
155
  # should not be seen:
156
156
  [ 123, [ %w(Content-Type text/html), %w(Content-Length 0) ], [] ]
157
+ when '/204'
158
+ buf = env['rack.input'].read # drain
159
+ [ 204, {}, [] ]
157
160
  else
158
161
  buf = env['rack.input'].read
159
162
  [ 201, {
@@ -271,6 +274,7 @@ def test_proxy_pass
271
274
  end
272
275
  end
273
276
 
277
+ check_204_on_put(host, port)
274
278
  check_forbidden_put(host, port)
275
279
  check_eof_body(host, port)
276
280
  check_pipelining(host, port)
@@ -639,4 +643,33 @@ def check_forbidden_put(host, port)
639
643
  ensure
640
644
  to_close.each(&:close)
641
645
  end
646
+
647
+ def check_204_on_put(host, port)
648
+ s = TCPSocket.new(host, port)
649
+ s.write("PUT /204 HTTP/1.1\r\nHost: example.com\r\n" \
650
+ "Content-Length: 11\r\n" \
651
+ "Content-Type: application/octet-stream\r\n" \
652
+ "\r\nhello worldPUT")
653
+ buf = s.readpartial(1024)
654
+ assert_match %r{\AHTTP/1\.1 204}, buf
655
+ assert_match %r{\r\n\r\n\z}, buf
656
+ refute_match %r{^Transfer-Encoding}i, buf
657
+ refute_match %r{^Content-Length}i, buf
658
+ assert_match %r{^Connection: keep-alive\r\n}, buf
659
+ assert_nil IO.select([s], nil, nil, 1), 'connection persists..'
660
+
661
+ # make sure another on the same connection works
662
+ s.write(" / HTTP/1.1\r\nHost: example.com\r\n" \
663
+ "Content-Length: 11\r\n" \
664
+ "Content-Type: application/octet-stream\r\n" \
665
+ "\r\nhello world")
666
+ buf = s.readpartial(1024)
667
+ assert_match %r{\r\n\r\nhello world\z}, buf
668
+ assert_match %r{\AHTTP/1\.1 201}, buf
669
+ assert_match(%r{^Content-Length: 11\r\n}, buf)
670
+ assert_match %r{^Connection: keep-alive\r\n}, buf
671
+ assert_nil IO.select([s], nil, nil, 1), 'connection persists..'
672
+ ensure
673
+ s.close if s
674
+ end
642
675
  end
@@ -86,6 +86,12 @@ def test_hijack
86
86
  assert_equal "rack.input contents: BLAH", res.body
87
87
  assert_equal 201, res.code.to_i
88
88
  assert_equal "1.0", res.http_version
89
+
90
+ # ancient "HTTP/0.9"
91
+ c = get_tcp_client(host, port)
92
+ c.write("GET /hijack_res\r\n\r\n")
93
+ res = Timeout.timeout(30) { c.read }
94
+ assert_equal 'response.hijacked', res
89
95
  ensure
90
96
  quit_wait(pid)
91
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yahns
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.0
4
+ version: 1.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - yahns hackers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-14 00:00:00.000000000 Z
11
+ date: 2016-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kgio