puma 3.12.0 → 3.12.6
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 +32 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/ext/puma_http11/http11_parser.c +3 -1
- data/ext/puma_http11/http11_parser.rl +3 -1
- data/ext/puma_http11/mini_ssl.c +12 -0
- data/lib/puma/binder.rb +10 -9
- data/lib/puma/cli.rb +2 -0
- data/lib/puma/client.rb +13 -2
- data/lib/puma/cluster.rb +2 -0
- data/lib/puma/commonlogger.rb +2 -0
- data/lib/puma/configuration.rb +2 -0
- data/lib/puma/const.rb +11 -1
- data/lib/puma/control_cli.rb +11 -9
- data/lib/puma/convenient.rb +2 -0
- data/lib/puma/daemon_ext.rb +2 -0
- data/lib/puma/delegation.rb +2 -0
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +12 -2
- data/lib/puma/events.rb +2 -0
- data/lib/puma/io_buffer.rb +2 -0
- data/lib/puma/java_io_buffer.rb +2 -0
- data/lib/puma/jruby_restart.rb +2 -0
- data/lib/puma/launcher.rb +4 -2
- data/lib/puma/minissl.rb +2 -0
- data/lib/puma/null_io.rb +2 -0
- data/lib/puma/plugin.rb +2 -0
- data/lib/puma/rack/builder.rb +2 -1
- data/lib/puma/reactor.rb +2 -0
- data/lib/puma/runner.rb +2 -0
- data/lib/puma/server.rb +56 -1
- data/lib/puma/single.rb +2 -0
- data/lib/puma/state_file.rb +2 -0
- data/lib/puma/tcp_logger.rb +2 -0
- data/lib/puma/thread_pool.rb +2 -0
- data/lib/puma/util.rb +1 -0
- data/lib/rack/handler/puma.rb +3 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da843833fd17b4bb2283f4c5161a1aa9367a6613455b8fbf31bae49393db4f80
|
4
|
+
data.tar.gz: bd9259270bd27f8421827c66e7f515044f51a7672c3dc755836d2a6b1240e84d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74d807145c97b7714c04ebf7858af57b1cdf00e87217b8a88428494718893f7670ffd27216c31164f57bd96984cd8e79f3c7f856d39c1b54c192965fe8ecdec8
|
7
|
+
data.tar.gz: e0616e41dceddc3b8aad69a5baab5b49007053d151bf2689de173495f3160900269bab94c539a47fe2bbdd2db1aab98a0df8177ece857a06bea6261c5d37a704
|
data/History.md
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
## Master
|
2
|
+
|
3
|
+
* x features
|
4
|
+
|
5
|
+
* x bugfixes
|
6
|
+
|
7
|
+
|
8
|
+
## 4.3.3 and 3.12.4 / 2020-02-28
|
9
|
+
* Bugfixes
|
10
|
+
* Fix: Fixes a problem where we weren't splitting headers correctly on newlines (#2132)
|
11
|
+
* Security
|
12
|
+
* Fix: Prevent HTTP Response splitting via CR in early hints.
|
13
|
+
|
14
|
+
## 4.3.2 and 3.12.3 / 2020-02-27
|
15
|
+
|
16
|
+
* Security
|
17
|
+
* Fix: Prevent HTTP Response splitting via CR/LF in header values. CVE-2020-5247.
|
18
|
+
|
19
|
+
## 4.3.1 and 3.12.2 / 2019-12-05
|
20
|
+
|
21
|
+
* Security
|
22
|
+
* Fix: a poorly-behaved client could use keepalive requests to monopolize Puma's reactor and create a denial of service attack. CVE-2019-16770.
|
23
|
+
|
24
|
+
## 3.12.1 / 2019-03-19
|
25
|
+
|
26
|
+
* 1 features
|
27
|
+
* Internal strings are frozen (#1649)
|
28
|
+
* 3 bugfixes
|
29
|
+
* Fix chunked ending check (#1607)
|
30
|
+
* Rack handler should use provided default host (#1700)
|
31
|
+
* Better support for detecting runtimes that support `fork` (#1630)
|
32
|
+
|
1
33
|
## 3.12.0 / 2018-07-13
|
2
34
|
|
3
35
|
* 5 features:
|
Binary file
|
Binary file
|
Binary file
|
@@ -14,12 +14,14 @@
|
|
14
14
|
|
15
15
|
/*
|
16
16
|
* capitalizes all lower-case ASCII characters,
|
17
|
-
* converts dashes to underscores.
|
17
|
+
* converts dashes to underscores, and underscores to commas.
|
18
18
|
*/
|
19
19
|
static void snake_upcase_char(char *c)
|
20
20
|
{
|
21
21
|
if (*c >= 'a' && *c <= 'z')
|
22
22
|
*c &= ~0x20;
|
23
|
+
else if (*c == '_')
|
24
|
+
*c = ',';
|
23
25
|
else if (*c == '-')
|
24
26
|
*c = '_';
|
25
27
|
}
|
@@ -12,12 +12,14 @@
|
|
12
12
|
|
13
13
|
/*
|
14
14
|
* capitalizes all lower-case ASCII characters,
|
15
|
-
* converts dashes to underscores.
|
15
|
+
* converts dashes to underscores, and underscores to commas.
|
16
16
|
*/
|
17
17
|
static void snake_upcase_char(char *c)
|
18
18
|
{
|
19
19
|
if (*c >= 'a' && *c <= 'z')
|
20
20
|
*c &= ~0x20;
|
21
|
+
else if (*c == '_')
|
22
|
+
*c = ',';
|
21
23
|
else if (*c == '-')
|
22
24
|
*c = '_';
|
23
25
|
}
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -433,6 +433,18 @@ void Init_mini_ssl(VALUE puma) {
|
|
433
433
|
mod = rb_define_module_under(puma, "MiniSSL");
|
434
434
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
435
435
|
|
436
|
+
// OpenSSL Build / Runtime/Load versions
|
437
|
+
|
438
|
+
/* Version of OpenSSL that Puma was compiled with */
|
439
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
440
|
+
|
441
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
442
|
+
/* Version of OpenSSL that Puma loaded with */
|
443
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
|
444
|
+
#else
|
445
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
446
|
+
#endif
|
447
|
+
|
436
448
|
rb_define_singleton_method(mod, "check", noop, 0);
|
437
449
|
|
438
450
|
eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
|
data/lib/puma/binder.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'uri'
|
2
4
|
require 'socket'
|
3
5
|
|
@@ -90,19 +92,19 @@ module Puma
|
|
90
92
|
case uri.scheme
|
91
93
|
when "tcp"
|
92
94
|
if fd = @inherited_fds.delete(str)
|
93
|
-
logger.log "* Inherited #{str}"
|
94
95
|
io = inherit_tcp_listener uri.host, uri.port, fd
|
96
|
+
logger.log "* Inherited #{str}"
|
95
97
|
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
|
96
|
-
logger.log "* Activated #{str}"
|
97
98
|
io = inherit_tcp_listener uri.host, uri.port, sock
|
99
|
+
logger.log "* Activated #{str}"
|
98
100
|
else
|
99
101
|
params = Util.parse_query uri.query
|
100
102
|
|
101
103
|
opt = params.key?('low_latency')
|
102
104
|
bak = params.fetch('backlog', 1024).to_i
|
103
105
|
|
104
|
-
logger.log "* Listening on #{str}"
|
105
106
|
io = add_tcp_listener uri.host, uri.port, opt, bak
|
107
|
+
logger.log "* Listening on #{str}"
|
106
108
|
end
|
107
109
|
|
108
110
|
@listeners << [str, io] if io
|
@@ -110,14 +112,12 @@ module Puma
|
|
110
112
|
path = "#{uri.host}#{uri.path}".gsub("%20", " ")
|
111
113
|
|
112
114
|
if fd = @inherited_fds.delete(str)
|
113
|
-
logger.log "* Inherited #{str}"
|
114
115
|
io = inherit_unix_listener path, fd
|
116
|
+
logger.log "* Inherited #{str}"
|
115
117
|
elsif sock = @activated_sockets.delete([ :unix, path ])
|
116
|
-
logger.log "* Activated #{str}"
|
117
118
|
io = inherit_unix_listener path, sock
|
119
|
+
logger.log "* Activated #{str}"
|
118
120
|
else
|
119
|
-
logger.log "* Listening on #{str}"
|
120
|
-
|
121
121
|
umask = nil
|
122
122
|
mode = nil
|
123
123
|
backlog = 1024
|
@@ -139,6 +139,7 @@ module Puma
|
|
139
139
|
end
|
140
140
|
|
141
141
|
io = add_unix_listener path, umask, mode, backlog
|
142
|
+
logger.log "* Listening on #{str}"
|
142
143
|
end
|
143
144
|
|
144
145
|
@listeners << [str, io]
|
@@ -204,11 +205,11 @@ module Puma
|
|
204
205
|
logger.log "* Inherited #{str}"
|
205
206
|
io = inherit_ssl_listener fd, ctx
|
206
207
|
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
|
207
|
-
logger.log "* Activated #{str}"
|
208
208
|
io = inherit_ssl_listener sock, ctx
|
209
|
+
logger.log "* Activated #{str}"
|
209
210
|
else
|
210
|
-
logger.log "* Listening on #{str}"
|
211
211
|
io = add_ssl_listener uri.host, uri.port, ctx
|
212
|
+
logger.log "* Listening on #{str}"
|
212
213
|
end
|
213
214
|
|
214
215
|
@listeners << [str, io] if io
|
data/lib/puma/cli.rb
CHANGED
data/lib/puma/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class IO
|
2
4
|
# We need to use this for a jruby work around on both 1.8 and 1.9.
|
3
5
|
# So this either creates the constant (on 1.8), or harmlessly
|
@@ -168,6 +170,7 @@ module Puma
|
|
168
170
|
if len == 0
|
169
171
|
@body.rewind
|
170
172
|
rest = io.read
|
173
|
+
rest = rest[2..-1] if rest.start_with?("\r\n")
|
171
174
|
@buffer = rest.empty? ? nil : rest
|
172
175
|
@requests_served += 1
|
173
176
|
@ready = true
|
@@ -241,8 +244,16 @@ module Puma
|
|
241
244
|
|
242
245
|
te = @env[TRANSFER_ENCODING2]
|
243
246
|
|
244
|
-
if te
|
245
|
-
|
247
|
+
if te
|
248
|
+
if te.include?(",")
|
249
|
+
te.split(",").each do |part|
|
250
|
+
if CHUNKED.casecmp(part.strip) == 0
|
251
|
+
return setup_chunked_body(body)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
elsif CHUNKED.casecmp(te) == 0
|
255
|
+
return setup_chunked_body(body)
|
256
|
+
end
|
246
257
|
end
|
247
258
|
|
248
259
|
@chunked_body = false
|
data/lib/puma/cluster.rb
CHANGED
data/lib/puma/commonlogger.rb
CHANGED
data/lib/puma/configuration.rb
CHANGED
data/lib/puma/const.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
module Puma
|
3
5
|
class UnsupportedOption < RuntimeError
|
4
6
|
end
|
@@ -98,7 +100,7 @@ module Puma
|
|
98
100
|
# too taxing on performance.
|
99
101
|
module Const
|
100
102
|
|
101
|
-
PUMA_VERSION = VERSION = "3.12.
|
103
|
+
PUMA_VERSION = VERSION = "3.12.6".freeze
|
102
104
|
CODE_NAME = "Llamas in Pajamas".freeze
|
103
105
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
104
106
|
|
@@ -116,6 +118,13 @@ module Puma
|
|
116
118
|
# sending data back
|
117
119
|
WRITE_TIMEOUT = 10
|
118
120
|
|
121
|
+
# How many requests to attempt inline before sending a client back to
|
122
|
+
# the reactor to be subject to normal ordering. The idea here is that
|
123
|
+
# we amortize the cost of going back to the reactor for a well behaved
|
124
|
+
# but very "greedy" client across 10 requests. This prevents a not
|
125
|
+
# well behaved client from monopolizing the thread forever.
|
126
|
+
MAX_FAST_INLINE = 10
|
127
|
+
|
119
128
|
# The original URI requested by the client.
|
120
129
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
121
130
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
@@ -219,6 +228,7 @@ module Puma
|
|
219
228
|
COLON = ": ".freeze
|
220
229
|
|
221
230
|
NEWLINE = "\n".freeze
|
231
|
+
HTTP_INJECTION_REGEX = /[\r\n]/.freeze
|
222
232
|
|
223
233
|
HIJACK_P = "rack.hijack?".freeze
|
224
234
|
HIJACK = "rack.hijack".freeze
|
data/lib/puma/control_cli.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
require_relative 'state_file'
|
5
|
+
require_relative 'const'
|
6
|
+
require_relative 'detect'
|
7
|
+
require_relative 'configuration'
|
6
8
|
require 'uri'
|
7
9
|
require 'socket'
|
8
10
|
|
@@ -129,7 +131,7 @@ module Puma
|
|
129
131
|
uri = URI.parse @control_url
|
130
132
|
|
131
133
|
# create server object by scheme
|
132
|
-
|
134
|
+
server = case uri.scheme
|
133
135
|
when "tcp"
|
134
136
|
TCPSocket.new uri.host, uri.port
|
135
137
|
when "unix"
|
@@ -147,9 +149,9 @@ module Puma
|
|
147
149
|
url = url + "?token=#{@control_auth_token}"
|
148
150
|
end
|
149
151
|
|
150
|
-
|
152
|
+
server << "GET #{url} HTTP/1.0\r\n\r\n"
|
151
153
|
|
152
|
-
unless data =
|
154
|
+
unless data = server.read
|
153
155
|
raise "Server closed connection before responding"
|
154
156
|
end
|
155
157
|
|
@@ -172,8 +174,8 @@ module Puma
|
|
172
174
|
message "Command #{@command} sent success"
|
173
175
|
message response.last if @command == "stats" || @command == "gc-stats"
|
174
176
|
end
|
175
|
-
|
176
|
-
|
177
|
+
ensure
|
178
|
+
server.close if server && !server.closed?
|
177
179
|
end
|
178
180
|
|
179
181
|
def send_signal
|
data/lib/puma/convenient.rb
CHANGED
data/lib/puma/daemon_ext.rb
CHANGED
data/lib/puma/delegation.rb
CHANGED
data/lib/puma/detect.rb
CHANGED
data/lib/puma/dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Puma
|
2
4
|
# The methods that are available for use inside the config file.
|
3
5
|
# These same methods are used in Puma cli and the rack handler
|
@@ -55,6 +57,14 @@ module Puma
|
|
55
57
|
@plugins.clear
|
56
58
|
end
|
57
59
|
|
60
|
+
def set_default_host(host)
|
61
|
+
@options[:default_host] = host
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_host
|
65
|
+
@options[:default_host] || Configuration::DefaultTCPHost
|
66
|
+
end
|
67
|
+
|
58
68
|
def inject(&blk)
|
59
69
|
instance_eval(&blk)
|
60
70
|
end
|
@@ -138,7 +148,7 @@ module Puma
|
|
138
148
|
# Define the TCP port to bind to. Use +bind+ for more advanced options.
|
139
149
|
#
|
140
150
|
def port(port, host=nil)
|
141
|
-
host ||=
|
151
|
+
host ||= default_host
|
142
152
|
bind "tcp://#{host}:#{port}"
|
143
153
|
end
|
144
154
|
|
@@ -493,7 +503,7 @@ module Puma
|
|
493
503
|
when Hash
|
494
504
|
if hdr = val[:header]
|
495
505
|
@options[:remote_address] = :header
|
496
|
-
@options[:remote_address_header] = "HTTP_" + hdr.upcase.
|
506
|
+
@options[:remote_address_header] = "HTTP_" + hdr.upcase.tr("-", "_")
|
497
507
|
else
|
498
508
|
raise "Invalid value for set_remote_address - #{val.inspect}"
|
499
509
|
end
|
data/lib/puma/events.rb
CHANGED
data/lib/puma/io_buffer.rb
CHANGED
data/lib/puma/java_io_buffer.rb
CHANGED
data/lib/puma/jruby_restart.rb
CHANGED
data/lib/puma/launcher.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puma/events'
|
2
4
|
require 'puma/detect'
|
3
5
|
|
@@ -63,8 +65,8 @@ module Puma
|
|
63
65
|
|
64
66
|
generate_restart_data
|
65
67
|
|
66
|
-
if clustered? &&
|
67
|
-
unsupported
|
68
|
+
if clustered? && !Process.respond_to?(:fork)
|
69
|
+
unsupported "worker mode not supported on #{RUBY_ENGINE} on this platform"
|
68
70
|
end
|
69
71
|
|
70
72
|
if @options[:daemon] && Puma.windows?
|
data/lib/puma/minissl.rb
CHANGED
data/lib/puma/null_io.rb
CHANGED
data/lib/puma/plugin.rb
CHANGED
data/lib/puma/rack/builder.rb
CHANGED
@@ -110,7 +110,8 @@ module Puma::Rack
|
|
110
110
|
|
111
111
|
has_options = false
|
112
112
|
server.valid_options.each do |name, description|
|
113
|
-
next if name.to_s
|
113
|
+
next if name.to_s =~ /^(Host|Port)[^a-zA-Z]/ # ignore handler's host and port options, we do our own.
|
114
|
+
|
114
115
|
info << " -O %-21s %s" % [name, description]
|
115
116
|
has_options = true
|
116
117
|
end
|
data/lib/puma/reactor.rb
CHANGED
data/lib/puma/runner.rb
CHANGED
data/lib/puma/server.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'stringio'
|
2
4
|
|
3
5
|
require 'puma/thread_pool'
|
@@ -468,6 +470,8 @@ module Puma
|
|
468
470
|
clean_thread_locals = @options[:clean_thread_locals]
|
469
471
|
close_socket = true
|
470
472
|
|
473
|
+
requests = 0
|
474
|
+
|
471
475
|
while true
|
472
476
|
case handle_request(client, buffer)
|
473
477
|
when false
|
@@ -481,7 +485,19 @@ module Puma
|
|
481
485
|
|
482
486
|
ThreadPool.clean_thread_locals if clean_thread_locals
|
483
487
|
|
484
|
-
|
488
|
+
requests += 1
|
489
|
+
|
490
|
+
check_for_more_data = @status == :run
|
491
|
+
|
492
|
+
if requests >= MAX_FAST_INLINE
|
493
|
+
# This will mean that reset will only try to use the data it already
|
494
|
+
# has buffered and won't try to read more data. What this means is that
|
495
|
+
# every client, independent of their request speed, gets treated like a slow
|
496
|
+
# one once every MAX_FAST_INLINE requests.
|
497
|
+
check_for_more_data = false
|
498
|
+
end
|
499
|
+
|
500
|
+
unless client.reset(check_for_more_data)
|
485
501
|
close_socket = false
|
486
502
|
client.set_timeout @persistent_timeout
|
487
503
|
@reactor.add client
|
@@ -637,6 +653,7 @@ module Puma
|
|
637
653
|
headers.each_pair do |k, vs|
|
638
654
|
if vs.respond_to?(:to_s) && !vs.to_s.empty?
|
639
655
|
vs.to_s.split(NEWLINE).each do |v|
|
656
|
+
next if possible_header_injection?(v)
|
640
657
|
fast_write client, "#{k}: #{v}\r\n"
|
641
658
|
end
|
642
659
|
else
|
@@ -648,6 +665,37 @@ module Puma
|
|
648
665
|
}
|
649
666
|
end
|
650
667
|
|
668
|
+
# Fixup any headers with , in the name to have _ now. We emit
|
669
|
+
# headers with , in them during the parse phase to avoid ambiguity
|
670
|
+
# with the - to _ conversion for critical headers. But here for
|
671
|
+
# compatibility, we'll convert them back. This code is written to
|
672
|
+
# avoid allocation in the common case (ie there are no headers
|
673
|
+
# with , in their names), that's why it has the extra conditionals.
|
674
|
+
|
675
|
+
to_delete = nil
|
676
|
+
to_add = nil
|
677
|
+
|
678
|
+
env.each do |k,v|
|
679
|
+
if k.start_with?("HTTP_") and k.include?(",") and k != "HTTP_TRANSFER,ENCODING"
|
680
|
+
if to_delete
|
681
|
+
to_delete << k
|
682
|
+
else
|
683
|
+
to_delete = [k]
|
684
|
+
end
|
685
|
+
|
686
|
+
unless to_add
|
687
|
+
to_add = {}
|
688
|
+
end
|
689
|
+
|
690
|
+
to_add[k.gsub(",", "_")] = v
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
if to_delete
|
695
|
+
to_delete.each { |k| env.delete(k) }
|
696
|
+
env.merge! to_add
|
697
|
+
end
|
698
|
+
|
651
699
|
# A rack extension. If the app writes #call'ables to this
|
652
700
|
# array, we will invoke them when the request is done.
|
653
701
|
#
|
@@ -735,6 +783,7 @@ module Puma
|
|
735
783
|
headers.each do |k, vs|
|
736
784
|
case k.downcase
|
737
785
|
when CONTENT_LENGTH2
|
786
|
+
next if possible_header_injection?(vs)
|
738
787
|
content_length = vs
|
739
788
|
next
|
740
789
|
when TRANSFER_ENCODING
|
@@ -747,6 +796,7 @@ module Puma
|
|
747
796
|
|
748
797
|
if vs.respond_to?(:to_s) && !vs.to_s.empty?
|
749
798
|
vs.to_s.split(NEWLINE).each do |v|
|
799
|
+
next if possible_header_injection?(v)
|
750
800
|
lines.append k, colon, v, line_ending
|
751
801
|
end
|
752
802
|
else
|
@@ -1013,5 +1063,10 @@ module Puma
|
|
1013
1063
|
def shutting_down?
|
1014
1064
|
@status == :stop || @status == :restart
|
1015
1065
|
end
|
1066
|
+
|
1067
|
+
def possible_header_injection?(header_value)
|
1068
|
+
HTTP_INJECTION_REGEX =~ header_value.to_s
|
1069
|
+
end
|
1070
|
+
private :possible_header_injection?
|
1016
1071
|
end
|
1017
1072
|
end
|
data/lib/puma/single.rb
CHANGED
data/lib/puma/state_file.rb
CHANGED
data/lib/puma/tcp_logger.rb
CHANGED
data/lib/puma/thread_pool.rb
CHANGED
data/lib/puma/util.rb
CHANGED
data/lib/rack/handler/puma.rb
CHANGED
@@ -49,6 +49,9 @@ module Rack
|
|
49
49
|
self.set_host_port_to_config(host, port, user_config)
|
50
50
|
end
|
51
51
|
|
52
|
+
if default_options[:Host]
|
53
|
+
file_config.set_default_host(default_options[:Host])
|
54
|
+
end
|
52
55
|
self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
|
53
56
|
|
54
57
|
user_config.app app
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.12.
|
4
|
+
version: 3.12.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
|
14
14
|
for Ruby/Rack applications. Puma is intended for use in both development and production
|
@@ -123,8 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
requirements: []
|
126
|
-
|
127
|
-
rubygems_version: 2.7.6
|
126
|
+
rubygems_version: 3.0.3
|
128
127
|
signing_key:
|
129
128
|
specification_version: 4
|
130
129
|
summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
|