puma 5.6.2-java → 5.6.4-java
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +5 -0
- data/lib/puma/client.rb +54 -11
- data/lib/puma/const.rb +6 -4
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/server.rb +3 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00fb5299edf47cd69e241fc63a66cb98ef7180e0df430651bab94adeec19bc9f
|
4
|
+
data.tar.gz: 70089c146221037a050001dbeca34da0be535268994214eace5d9f1c670684b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da00b1d9d4d509cbe4f5da700091188b6559a61c932331cf7e4aef8f424b426846296df0804cb5b06f23033a3d5b6d8d31dcb512444ae276b0071b3e653f5f2e
|
7
|
+
data.tar.gz: efe8517f061dc996c83cec30110c3b8a84e6563dcba33e6416ad98799f685e0145bbd6856c7b7941cbf5682de44c73b56221022ca8231b8cbee7afe5faa78c15
|
data/History.md
CHANGED
data/lib/puma/client.rb
CHANGED
@@ -23,6 +23,8 @@ module Puma
|
|
23
23
|
|
24
24
|
class ConnectionError < RuntimeError; end
|
25
25
|
|
26
|
+
class HttpParserError501 < IOError; end
|
27
|
+
|
26
28
|
# An instance of this class represents a unique request from a client.
|
27
29
|
# For example, this could be a web request from a browser or from CURL.
|
28
30
|
#
|
@@ -35,7 +37,21 @@ module Puma
|
|
35
37
|
# Instances of this class are responsible for knowing if
|
36
38
|
# the header and body are fully buffered via the `try_to_finish` method.
|
37
39
|
# They can be used to "time out" a response via the `timeout_at` reader.
|
40
|
+
#
|
38
41
|
class Client
|
42
|
+
|
43
|
+
# this tests all values but the last, which must be chunked
|
44
|
+
ALLOWED_TRANSFER_ENCODING = %w[compress deflate gzip].freeze
|
45
|
+
|
46
|
+
# chunked body validation
|
47
|
+
CHUNK_SIZE_INVALID = /[^\h]/.freeze
|
48
|
+
CHUNK_VALID_ENDING = "\r\n".freeze
|
49
|
+
|
50
|
+
# Content-Length header value validation
|
51
|
+
CONTENT_LENGTH_VALUE_INVALID = /[^\d]/.freeze
|
52
|
+
|
53
|
+
TE_ERR_MSG = 'Invalid Transfer-Encoding'
|
54
|
+
|
39
55
|
# The object used for a request with no body. All requests with
|
40
56
|
# no body share this one object since it has no state.
|
41
57
|
EmptyBody = NullIO.new
|
@@ -302,16 +318,27 @@ module Puma
|
|
302
318
|
body = @parser.body
|
303
319
|
|
304
320
|
te = @env[TRANSFER_ENCODING2]
|
305
|
-
|
306
321
|
if te
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
322
|
+
te_lwr = te.downcase
|
323
|
+
if te.include? ','
|
324
|
+
te_ary = te_lwr.split ','
|
325
|
+
te_count = te_ary.count CHUNKED
|
326
|
+
te_valid = te_ary[0..-2].all? { |e| ALLOWED_TRANSFER_ENCODING.include? e }
|
327
|
+
if te_ary.last == CHUNKED && te_count == 1 && te_valid
|
328
|
+
@env.delete TRANSFER_ENCODING2
|
329
|
+
return setup_chunked_body body
|
330
|
+
elsif te_count >= 1
|
331
|
+
raise HttpParserError , "#{TE_ERR_MSG}, multiple chunked: '#{te}'"
|
332
|
+
elsif !te_valid
|
333
|
+
raise HttpParserError501, "#{TE_ERR_MSG}, unknown value: '#{te}'"
|
312
334
|
end
|
313
|
-
elsif
|
314
|
-
|
335
|
+
elsif te_lwr == CHUNKED
|
336
|
+
@env.delete TRANSFER_ENCODING2
|
337
|
+
return setup_chunked_body body
|
338
|
+
elsif ALLOWED_TRANSFER_ENCODING.include? te_lwr
|
339
|
+
raise HttpParserError , "#{TE_ERR_MSG}, single value must be chunked: '#{te}'"
|
340
|
+
else
|
341
|
+
raise HttpParserError501 , "#{TE_ERR_MSG}, unknown value: '#{te}'"
|
315
342
|
end
|
316
343
|
end
|
317
344
|
|
@@ -319,7 +346,12 @@ module Puma
|
|
319
346
|
|
320
347
|
cl = @env[CONTENT_LENGTH]
|
321
348
|
|
322
|
-
|
349
|
+
if cl
|
350
|
+
# cannot contain characters that are not \d
|
351
|
+
if cl =~ CONTENT_LENGTH_VALUE_INVALID
|
352
|
+
raise HttpParserError, "Invalid Content-Length: #{cl.inspect}"
|
353
|
+
end
|
354
|
+
else
|
323
355
|
@buffer = body.empty? ? nil : body
|
324
356
|
@body = EmptyBody
|
325
357
|
set_ready
|
@@ -478,7 +510,13 @@ module Puma
|
|
478
510
|
while !io.eof?
|
479
511
|
line = io.gets
|
480
512
|
if line.end_with?("\r\n")
|
481
|
-
|
513
|
+
# Puma doesn't process chunk extensions, but should parse if they're
|
514
|
+
# present, which is the reason for the semicolon regex
|
515
|
+
chunk_hex = line.strip[/\A[^;]+/]
|
516
|
+
if chunk_hex =~ CHUNK_SIZE_INVALID
|
517
|
+
raise HttpParserError, "Invalid chunk size: '#{chunk_hex}'"
|
518
|
+
end
|
519
|
+
len = chunk_hex.to_i(16)
|
482
520
|
if len == 0
|
483
521
|
@in_last_chunk = true
|
484
522
|
@body.rewind
|
@@ -509,7 +547,12 @@ module Puma
|
|
509
547
|
|
510
548
|
case
|
511
549
|
when got == len
|
512
|
-
|
550
|
+
# proper chunked segment must end with "\r\n"
|
551
|
+
if part.end_with? CHUNK_VALID_ENDING
|
552
|
+
write_chunk(part[0..-3]) # to skip the ending \r\n
|
553
|
+
else
|
554
|
+
raise HttpParserError, "Chunk size mismatch"
|
555
|
+
end
|
513
556
|
when got <= len - 2
|
514
557
|
write_chunk(part)
|
515
558
|
@partial_part_left = len - part.size
|
data/lib/puma/const.rb
CHANGED
@@ -76,7 +76,7 @@ module Puma
|
|
76
76
|
508 => 'Loop Detected',
|
77
77
|
510 => 'Not Extended',
|
78
78
|
511 => 'Network Authentication Required'
|
79
|
-
}
|
79
|
+
}.freeze
|
80
80
|
|
81
81
|
# For some HTTP status codes the client only expects headers.
|
82
82
|
#
|
@@ -85,7 +85,7 @@ module Puma
|
|
85
85
|
204 => true,
|
86
86
|
205 => true,
|
87
87
|
304 => true
|
88
|
-
}
|
88
|
+
}.freeze
|
89
89
|
|
90
90
|
# Frequently used constants when constructing requests or responses. Many times
|
91
91
|
# the constant just refers to a string with the same contents. Using these constants
|
@@ -100,7 +100,7 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "5.6.
|
103
|
+
PUMA_VERSION = VERSION = "5.6.4".freeze
|
104
104
|
CODE_NAME = "Birdie's Version".freeze
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
@@ -145,9 +145,11 @@ module Puma
|
|
145
145
|
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\n".freeze,
|
146
146
|
# Indicate that there was an internal error, obviously.
|
147
147
|
500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze,
|
148
|
+
# Incorrect or invalid header value
|
149
|
+
501 => "HTTP/1.1 501 Not Implemented\r\n\r\n".freeze,
|
148
150
|
# A common header for indicating the server is too busy. Not used yet.
|
149
151
|
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
|
150
|
-
}
|
152
|
+
}.freeze
|
151
153
|
|
152
154
|
# The basic max request size we'll try to read.
|
153
155
|
CHUNK_SIZE = 16 * 1024
|
data/lib/puma/puma_http11.jar
CHANGED
Binary file
|
data/lib/puma/server.rb
CHANGED
@@ -515,6 +515,9 @@ module Puma
|
|
515
515
|
when HttpParserError
|
516
516
|
client.write_error(400)
|
517
517
|
@events.parse_error e, client
|
518
|
+
when HttpParserError501
|
519
|
+
client.write_error(501)
|
520
|
+
@events.parse_error e, client
|
518
521
|
else
|
519
522
|
client.write_error(500)
|
520
523
|
@events.unknown_error e, nil, "Read"
|