rack 2.2.20 → 3.0.0.beta1
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.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +134 -161
- data/CONTRIBUTING.md +53 -47
- data/MIT-LICENSE +1 -1
- data/README.md +287 -0
- data/Rakefile +40 -7
- data/SPEC.rdoc +166 -125
- data/contrib/LICENSE.md +7 -0
- data/contrib/logo.webp +0 -0
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +3 -1
- data/lib/rack/auth/basic.rb +2 -1
- data/lib/rack/auth/digest/md5.rb +1 -131
- data/lib/rack/auth/digest/nonce.rb +1 -53
- data/lib/rack/auth/digest/params.rb +1 -54
- data/lib/rack/auth/digest/request.rb +1 -43
- data/lib/rack/auth/digest.rb +256 -0
- data/lib/rack/body_proxy.rb +3 -1
- data/lib/rack/builder.rb +60 -42
- data/lib/rack/cascade.rb +2 -0
- data/lib/rack/chunked.rb +16 -13
- data/lib/rack/common_logger.rb +24 -20
- data/lib/rack/conditional_get.rb +18 -15
- data/lib/rack/constants.rb +62 -0
- data/lib/rack/content_length.rb +12 -16
- data/lib/rack/content_type.rb +8 -5
- data/lib/rack/deflater.rb +40 -26
- data/lib/rack/directory.rb +9 -3
- data/lib/rack/etag.rb +14 -23
- data/lib/rack/events.rb +4 -0
- data/lib/rack/file.rb +2 -0
- data/lib/rack/files.rb +15 -17
- data/lib/rack/head.rb +9 -8
- data/lib/rack/headers.rb +154 -0
- data/lib/rack/lint.rb +740 -649
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +7 -17
- data/lib/rack/method_override.rb +5 -1
- data/lib/rack/mime.rb +8 -0
- data/lib/rack/mock.rb +1 -300
- data/lib/rack/mock_request.rb +166 -0
- data/lib/rack/mock_response.rb +124 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +121 -139
- data/lib/rack/multipart/uploaded_file.rb +4 -0
- data/lib/rack/multipart.rb +20 -40
- data/lib/rack/null_logger.rb +9 -0
- data/lib/rack/query_parser.rb +78 -91
- data/lib/rack/recursive.rb +2 -0
- data/lib/rack/reloader.rb +0 -2
- data/lib/rack/request.rb +190 -95
- data/lib/rack/response.rb +131 -61
- data/lib/rack/rewindable_input.rb +24 -5
- data/lib/rack/runtime.rb +7 -6
- data/lib/rack/sendfile.rb +39 -64
- data/lib/rack/show_exceptions.rb +15 -2
- data/lib/rack/show_status.rb +17 -7
- data/lib/rack/static.rb +9 -10
- data/lib/rack/tempfile_reaper.rb +15 -4
- data/lib/rack/urlmap.rb +4 -2
- data/lib/rack/utils.rb +212 -202
- data/lib/rack/version.rb +9 -4
- data/lib/rack.rb +5 -76
- data/rack.gemspec +6 -6
- metadata +22 -31
- data/README.rdoc +0 -355
- data/bin/rackup +0 -5
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +0 -150
- data/contrib/rack_logo.svg +0 -164
- data/lib/rack/core_ext/regexp.rb +0 -14
- data/lib/rack/handler/cgi.rb +0 -59
- data/lib/rack/handler/fastcgi.rb +0 -100
- data/lib/rack/handler/lsws.rb +0 -61
- data/lib/rack/handler/scgi.rb +0 -71
- data/lib/rack/handler/thin.rb +0 -34
- data/lib/rack/handler/webrick.rb +0 -129
- data/lib/rack/handler.rb +0 -104
- data/lib/rack/lobster.rb +0 -70
- data/lib/rack/server.rb +0 -466
- data/lib/rack/session/abstract/id.rb +0 -523
- data/lib/rack/session/cookie.rb +0 -203
- data/lib/rack/session/memcache.rb +0 -10
- data/lib/rack/session/pool.rb +0 -90
data/lib/rack/null_logger.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'constants'
|
4
|
+
|
3
5
|
module Rack
|
4
6
|
class NullLogger
|
5
7
|
def initialize(app)
|
@@ -22,6 +24,11 @@ module Rack
|
|
22
24
|
def warn? ; end
|
23
25
|
def error? ; end
|
24
26
|
def fatal? ; end
|
27
|
+
def debug! ; end
|
28
|
+
def error! ; end
|
29
|
+
def fatal! ; end
|
30
|
+
def info! ; end
|
31
|
+
def warn! ; end
|
25
32
|
def level ; end
|
26
33
|
def progname ; end
|
27
34
|
def datetime_format ; end
|
@@ -34,6 +41,8 @@ module Rack
|
|
34
41
|
def sev_threshold=(sev_threshold); end
|
35
42
|
def close ; end
|
36
43
|
def add(severity, message = nil, progname = nil, &block); end
|
44
|
+
def log(severity, message = nil, progname = nil, &block); end
|
37
45
|
def <<(msg); end
|
46
|
+
def reopen(logdev = nil); end
|
38
47
|
end
|
39
48
|
end
|
data/lib/rack/query_parser.rb
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
module Rack
|
4
4
|
class QueryParser
|
5
|
-
|
6
|
-
|
7
|
-
DEFAULT_SEP = /[&;] */n
|
5
|
+
DEFAULT_SEP = /[&] */n
|
8
6
|
COMMON_SEP = { ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }
|
9
7
|
|
10
8
|
# ParameterTypeError is the error that is raised when incoming structural
|
@@ -16,62 +14,39 @@ module Rack
|
|
16
14
|
# sequence.
|
17
15
|
class InvalidParameterError < ArgumentError; end
|
18
16
|
|
19
|
-
#
|
20
|
-
#
|
21
|
-
class
|
22
|
-
end
|
23
|
-
|
24
|
-
# ParamsTooDeepError is the old name for the error that is raised when params
|
25
|
-
# are recursively nested over the specified limit. Make it the same as
|
26
|
-
# as QueryLimitError, so that code that rescues ParamsTooDeepError error
|
27
|
-
# to handle bad query strings also now handles other limits.
|
28
|
-
ParamsTooDeepError = QueryLimitError
|
17
|
+
# ParamsTooDeepError is the error that is raised when params are recursively
|
18
|
+
# nested over the specified limit.
|
19
|
+
class ParamsTooDeepError < RangeError; end
|
29
20
|
|
30
|
-
def self.make_default(
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
attr_reader :key_space_limit, :param_depth_limit
|
35
|
-
|
36
|
-
env_int = lambda do |key, val|
|
37
|
-
if str_val = ENV[key]
|
38
|
-
begin
|
39
|
-
val = Integer(str_val, 10)
|
40
|
-
rescue ArgumentError
|
41
|
-
raise ArgumentError, "non-integer value provided for environment variable #{key}"
|
42
|
-
end
|
21
|
+
def self.make_default(_key_space_limit=(not_deprecated = true; nil), param_depth_limit)
|
22
|
+
unless not_deprecated
|
23
|
+
warn("`first argument `key_space limit` is deprecated and no longer has an effect. Please call with only one argument, which will be required in a future version of Rack", uplevel: 1)
|
43
24
|
end
|
44
25
|
|
45
|
-
|
26
|
+
new Params, param_depth_limit
|
46
27
|
end
|
47
28
|
|
48
|
-
|
49
|
-
private_constant :BYTESIZE_LIMIT
|
29
|
+
attr_reader :param_depth_limit
|
50
30
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
31
|
+
def initialize(params_class, _key_space_limit=(not_deprecated = true; nil), param_depth_limit)
|
32
|
+
unless not_deprecated
|
33
|
+
warn("`second argument `key_space limit` is deprecated and no longer has an effect. Please call with only two arguments, which will be required in a future version of Rack", uplevel: 1)
|
34
|
+
end
|
55
35
|
|
56
|
-
def initialize(params_class, key_space_limit, param_depth_limit, bytesize_limit: BYTESIZE_LIMIT, params_limit: PARAMS_LIMIT)
|
57
36
|
@params_class = params_class
|
58
|
-
@key_space_limit = key_space_limit
|
59
37
|
@param_depth_limit = param_depth_limit
|
60
|
-
@bytesize_limit = bytesize_limit
|
61
|
-
@params_limit = params_limit
|
62
38
|
end
|
63
39
|
|
64
40
|
# Stolen from Mongrel, with some small modifications:
|
65
|
-
# Parses a query string by breaking it up at the '&'
|
66
|
-
#
|
67
|
-
#
|
68
|
-
|
69
|
-
def parse_query(qs, d = nil, &unescaper)
|
41
|
+
# Parses a query string by breaking it up at the '&'. You can also use this
|
42
|
+
# to parse cookies by changing the characters used in the second parameter
|
43
|
+
# (which defaults to '&').
|
44
|
+
def parse_query(qs, separator = nil, &unescaper)
|
70
45
|
unescaper ||= method(:unescape)
|
71
46
|
|
72
47
|
params = make_params
|
73
48
|
|
74
|
-
|
49
|
+
(qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
|
75
50
|
next if p.empty?
|
76
51
|
k, v = p.split('=', 2).map!(&unescaper)
|
77
52
|
|
@@ -94,14 +69,14 @@ module Rack
|
|
94
69
|
# query strings with parameters of conflicting types, in this case a
|
95
70
|
# ParameterTypeError is raised. Users are encouraged to return a 400 in this
|
96
71
|
# case.
|
97
|
-
def parse_nested_query(qs,
|
72
|
+
def parse_nested_query(qs, separator = nil)
|
98
73
|
params = make_params
|
99
74
|
|
100
75
|
unless qs.nil? || qs.empty?
|
101
|
-
|
76
|
+
(qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
|
102
77
|
k, v = p.split('=', 2).map! { |s| unescape(s) }
|
103
78
|
|
104
|
-
|
79
|
+
_normalize_params(params, k, v, 0)
|
105
80
|
end
|
106
81
|
end
|
107
82
|
|
@@ -112,58 +87,89 @@ module Rack
|
|
112
87
|
|
113
88
|
# normalize_params recursively expands parameters into structural types. If
|
114
89
|
# the structural types represented by two different parameter names are in
|
115
|
-
# conflict, a ParameterTypeError is raised.
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
name
|
120
|
-
|
121
|
-
after = $' || ''
|
90
|
+
# conflict, a ParameterTypeError is raised. The depth argument is deprecated
|
91
|
+
# and should no longer be used, it is kept for backwards compatibility with
|
92
|
+
# earlier versions of rack.
|
93
|
+
def normalize_params(params, name, v, _depth=nil)
|
94
|
+
_normalize_params(params, name, v, 0)
|
95
|
+
end
|
122
96
|
|
123
|
-
|
124
|
-
|
125
|
-
|
97
|
+
private def _normalize_params(params, name, v, depth)
|
98
|
+
raise ParamsTooDeepError if depth >= param_depth_limit
|
99
|
+
|
100
|
+
if !name
|
101
|
+
# nil name, treat same as empty string (required by tests)
|
102
|
+
k = after = ''
|
103
|
+
elsif depth == 0
|
104
|
+
# Start of parsing, don't treat [] or [ at start of string specially
|
105
|
+
if start = name.index('[', 1)
|
106
|
+
# Start of parameter nesting, use part before brackets as key
|
107
|
+
k = name[0, start]
|
108
|
+
after = name[start, name.length]
|
126
109
|
else
|
127
|
-
|
110
|
+
# Plain parameter with no nesting
|
111
|
+
k = name
|
112
|
+
after = ''
|
128
113
|
end
|
114
|
+
elsif name.start_with?('[]')
|
115
|
+
# Array nesting
|
116
|
+
k = '[]'
|
117
|
+
after = name[2, name.length]
|
118
|
+
elsif name.start_with?('[') && (start = name.index(']', 1))
|
119
|
+
# Hash nesting, use the part inside brackets as the key
|
120
|
+
k = name[1, start-1]
|
121
|
+
after = name[start+1, name.length]
|
122
|
+
else
|
123
|
+
# Probably malformed input, nested but not starting with [
|
124
|
+
# treat full name as key for backwards compatibility.
|
125
|
+
k = name
|
126
|
+
after = ''
|
129
127
|
end
|
130
128
|
|
129
|
+
return if k.empty?
|
130
|
+
|
131
|
+
v ||= String.new
|
132
|
+
|
131
133
|
if after == ''
|
132
|
-
|
134
|
+
if k == '[]' && depth != 0
|
135
|
+
return [v]
|
136
|
+
else
|
137
|
+
params[k] = v
|
138
|
+
end
|
133
139
|
elsif after == "["
|
134
140
|
params[name] = v
|
135
141
|
elsif after == "[]"
|
136
142
|
params[k] ||= []
|
137
143
|
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
138
144
|
params[k] << v
|
139
|
-
elsif after
|
140
|
-
|
145
|
+
elsif after.start_with?('[]')
|
146
|
+
# Recognize x[][y] (hash inside array) parameters
|
147
|
+
unless after[2] == '[' && after.end_with?(']') && (child_key = after[3, after.length-4]) && !child_key.empty? && !child_key.index('[') && !child_key.index(']')
|
148
|
+
# Handle other nested array parameters
|
149
|
+
child_key = after[2, after.length]
|
150
|
+
end
|
141
151
|
params[k] ||= []
|
142
152
|
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
143
153
|
if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
|
144
|
-
|
154
|
+
_normalize_params(params[k].last, child_key, v, depth + 1)
|
145
155
|
else
|
146
|
-
params[k] <<
|
156
|
+
params[k] << _normalize_params(make_params, child_key, v, depth + 1)
|
147
157
|
end
|
148
158
|
else
|
149
159
|
params[k] ||= make_params
|
150
160
|
raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
|
151
|
-
params[k] =
|
161
|
+
params[k] = _normalize_params(params[k], after, v, depth + 1)
|
152
162
|
end
|
153
163
|
|
154
164
|
params
|
155
165
|
end
|
156
166
|
|
157
167
|
def make_params
|
158
|
-
@params_class.new
|
159
|
-
end
|
160
|
-
|
161
|
-
def new_space_limit(key_space_limit)
|
162
|
-
self.class.new @params_class, key_space_limit, param_depth_limit
|
168
|
+
@params_class.new
|
163
169
|
end
|
164
170
|
|
165
171
|
def new_depth_limit(param_depth_limit)
|
166
|
-
self.class.new @params_class,
|
172
|
+
self.class.new @params_class, param_depth_limit
|
167
173
|
end
|
168
174
|
|
169
175
|
private
|
@@ -184,29 +190,12 @@ module Rack
|
|
184
190
|
true
|
185
191
|
end
|
186
192
|
|
187
|
-
def
|
188
|
-
|
189
|
-
if qs.bytesize > @bytesize_limit
|
190
|
-
raise QueryLimitError, "total query size exceeds limit (#{@bytesize_limit})"
|
191
|
-
end
|
192
|
-
|
193
|
-
if (param_count = qs.count(sep.is_a?(String) ? sep : '&;')) >= @params_limit
|
194
|
-
raise QueryLimitError, "total number of query parameters (#{param_count+1}) exceeds limit (#{@params_limit})"
|
195
|
-
end
|
196
|
-
|
197
|
-
qs
|
198
|
-
else
|
199
|
-
''
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
def unescape(string)
|
204
|
-
Utils.unescape(string)
|
193
|
+
def unescape(s)
|
194
|
+
Utils.unescape(s)
|
205
195
|
end
|
206
196
|
|
207
197
|
class Params
|
208
|
-
def initialize
|
209
|
-
@limit = limit
|
198
|
+
def initialize
|
210
199
|
@size = 0
|
211
200
|
@params = {}
|
212
201
|
end
|
@@ -216,8 +205,6 @@ module Rack
|
|
216
205
|
end
|
217
206
|
|
218
207
|
def []=(key, value)
|
219
|
-
@size += key.size if key && !@params.key?(key)
|
220
|
-
raise ParamsTooDeepError, 'exceeded available parameter key space' if @size > @limit
|
221
208
|
@params[key] = value
|
222
209
|
end
|
223
210
|
|
data/lib/rack/recursive.rb
CHANGED
data/lib/rack/reloader.rb
CHANGED
@@ -22,8 +22,6 @@ module Rack
|
|
22
22
|
# It is performing a check/reload cycle at the start of every request, but
|
23
23
|
# also respects a cool down time, during which nothing will be done.
|
24
24
|
class Reloader
|
25
|
-
(require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
|
26
|
-
|
27
25
|
def initialize(app, cooldown = 10, backend = Stat)
|
28
26
|
@app = app
|
29
27
|
@cooldown = cooldown
|