rack 2.2.17 → 3.0.18
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 +292 -74
- data/CONTRIBUTING.md +53 -47
- data/MIT-LICENSE +1 -1
- data/README.md +336 -0
- data/SPEC.rdoc +174 -126
- 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 -3
- 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 +21 -3
- data/lib/rack/builder.rb +83 -63
- data/lib/rack/cascade.rb +2 -0
- data/lib/rack/chunked.rb +16 -13
- data/lib/rack/common_logger.rb +22 -17
- data/lib/rack/conditional_get.rb +18 -15
- data/lib/rack/constants.rb +64 -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 +17 -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 +758 -646
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +3 -8
- 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 +155 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +127 -69
- 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 -46
- data/lib/rack/recursive.rb +2 -0
- data/lib/rack/reloader.rb +0 -2
- data/lib/rack/request.rb +224 -106
- data/lib/rack/response.rb +138 -61
- data/lib/rack/rewindable_input.rb +24 -5
- data/lib/rack/runtime.rb +7 -6
- data/lib/rack/sendfile.rb +30 -25
- data/lib/rack/show_exceptions.rb +15 -2
- data/lib/rack/show_status.rb +17 -7
- data/lib/rack/static.rb +8 -8
- data/lib/rack/tempfile_reaper.rb +15 -4
- data/lib/rack/urlmap.rb +3 -1
- data/lib/rack/utils.rb +206 -180
- data/lib/rack/version.rb +9 -4
- data/lib/rack.rb +13 -87
- metadata +15 -35
- data/README.rdoc +0 -347
- data/Rakefile +0 -130
- 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/contrib/rdoc.css +0 -412
- data/example/lobster.ru +0 -6
- data/example/protectedlobster.rb +0 -16
- data/example/protectedlobster.ru +0 -10
- 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 -36
- 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/rack.gemspec +0 -46
data/lib/rack/query_parser.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'uri'
|
4
|
+
|
3
5
|
module Rack
|
4
6
|
class QueryParser
|
5
|
-
|
6
|
-
|
7
|
-
DEFAULT_SEP = /[&;] */n
|
7
|
+
DEFAULT_SEP = /[&] */n
|
8
8
|
COMMON_SEP = { ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }
|
9
9
|
|
10
10
|
# ParameterTypeError is the error that is raised when incoming structural
|
@@ -27,11 +27,15 @@ module Rack
|
|
27
27
|
# to handle bad query strings also now handles other limits.
|
28
28
|
ParamsTooDeepError = QueryLimitError
|
29
29
|
|
30
|
-
def self.make_default(
|
31
|
-
|
30
|
+
def self.make_default(_key_space_limit=(not_deprecated = true; nil), param_depth_limit, **options)
|
31
|
+
unless not_deprecated
|
32
|
+
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)
|
33
|
+
end
|
34
|
+
|
35
|
+
new Params, param_depth_limit, **options
|
32
36
|
end
|
33
37
|
|
34
|
-
attr_reader :
|
38
|
+
attr_reader :param_depth_limit
|
35
39
|
|
36
40
|
env_int = lambda do |key, val|
|
37
41
|
if str_val = ENV[key]
|
@@ -51,25 +55,27 @@ module Rack
|
|
51
55
|
PARAMS_LIMIT = env_int.call("RACK_QUERY_PARSER_PARAMS_LIMIT", 4096)
|
52
56
|
private_constant :PARAMS_LIMIT
|
53
57
|
|
54
|
-
def initialize(params_class,
|
58
|
+
def initialize(params_class, _key_space_limit=(not_deprecated = true; nil), param_depth_limit, bytesize_limit: BYTESIZE_LIMIT, params_limit: PARAMS_LIMIT)
|
59
|
+
unless not_deprecated
|
60
|
+
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)
|
61
|
+
end
|
62
|
+
|
55
63
|
@params_class = params_class
|
56
|
-
@key_space_limit = key_space_limit
|
57
64
|
@param_depth_limit = param_depth_limit
|
58
65
|
@bytesize_limit = bytesize_limit
|
59
66
|
@params_limit = params_limit
|
60
67
|
end
|
61
68
|
|
62
69
|
# Stolen from Mongrel, with some small modifications:
|
63
|
-
# Parses a query string by breaking it up at the '&'
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
def parse_query(qs, d = nil, &unescaper)
|
70
|
+
# Parses a query string by breaking it up at the '&'. You can also use this
|
71
|
+
# to parse cookies by changing the characters used in the second parameter
|
72
|
+
# (which defaults to '&').
|
73
|
+
def parse_query(qs, separator = nil, &unescaper)
|
68
74
|
unescaper ||= method(:unescape)
|
69
75
|
|
70
76
|
params = make_params
|
71
77
|
|
72
|
-
check_query_string(qs,
|
78
|
+
check_query_string(qs, separator).split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
|
73
79
|
next if p.empty?
|
74
80
|
k, v = p.split('=', 2).map!(&unescaper)
|
75
81
|
|
@@ -92,14 +98,14 @@ module Rack
|
|
92
98
|
# query strings with parameters of conflicting types, in this case a
|
93
99
|
# ParameterTypeError is raised. Users are encouraged to return a 400 in this
|
94
100
|
# case.
|
95
|
-
def parse_nested_query(qs,
|
101
|
+
def parse_nested_query(qs, separator = nil)
|
96
102
|
params = make_params
|
97
103
|
|
98
104
|
unless qs.nil? || qs.empty?
|
99
|
-
check_query_string(qs,
|
105
|
+
check_query_string(qs, separator).split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
|
100
106
|
k, v = p.split('=', 2).map! { |s| unescape(s) }
|
101
107
|
|
102
|
-
|
108
|
+
_normalize_params(params, k, v, 0)
|
103
109
|
end
|
104
110
|
end
|
105
111
|
|
@@ -110,58 +116,87 @@ module Rack
|
|
110
116
|
|
111
117
|
# normalize_params recursively expands parameters into structural types. If
|
112
118
|
# the structural types represented by two different parameter names are in
|
113
|
-
# conflict, a ParameterTypeError is raised.
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
name
|
118
|
-
|
119
|
-
after = $' || ''
|
119
|
+
# conflict, a ParameterTypeError is raised. The depth argument is deprecated
|
120
|
+
# and should no longer be used, it is kept for backwards compatibility with
|
121
|
+
# earlier versions of rack.
|
122
|
+
def normalize_params(params, name, v, _depth=nil)
|
123
|
+
_normalize_params(params, name, v, 0)
|
124
|
+
end
|
120
125
|
|
121
|
-
|
122
|
-
|
123
|
-
|
126
|
+
private def _normalize_params(params, name, v, depth)
|
127
|
+
raise ParamsTooDeepError if depth >= param_depth_limit
|
128
|
+
|
129
|
+
if !name
|
130
|
+
# nil name, treat same as empty string (required by tests)
|
131
|
+
k = after = ''
|
132
|
+
elsif depth == 0
|
133
|
+
# Start of parsing, don't treat [] or [ at start of string specially
|
134
|
+
if start = name.index('[', 1)
|
135
|
+
# Start of parameter nesting, use part before brackets as key
|
136
|
+
k = name[0, start]
|
137
|
+
after = name[start, name.length]
|
124
138
|
else
|
125
|
-
|
139
|
+
# Plain parameter with no nesting
|
140
|
+
k = name
|
141
|
+
after = ''
|
126
142
|
end
|
143
|
+
elsif name.start_with?('[]')
|
144
|
+
# Array nesting
|
145
|
+
k = '[]'
|
146
|
+
after = name[2, name.length]
|
147
|
+
elsif name.start_with?('[') && (start = name.index(']', 1))
|
148
|
+
# Hash nesting, use the part inside brackets as the key
|
149
|
+
k = name[1, start-1]
|
150
|
+
after = name[start+1, name.length]
|
151
|
+
else
|
152
|
+
# Probably malformed input, nested but not starting with [
|
153
|
+
# treat full name as key for backwards compatibility.
|
154
|
+
k = name
|
155
|
+
after = ''
|
127
156
|
end
|
128
157
|
|
158
|
+
return if k.empty?
|
159
|
+
|
129
160
|
if after == ''
|
130
|
-
|
161
|
+
if k == '[]' && depth != 0
|
162
|
+
return [v]
|
163
|
+
else
|
164
|
+
params[k] = v
|
165
|
+
end
|
131
166
|
elsif after == "["
|
132
167
|
params[name] = v
|
133
168
|
elsif after == "[]"
|
134
169
|
params[k] ||= []
|
135
170
|
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
136
171
|
params[k] << v
|
137
|
-
elsif after
|
138
|
-
|
172
|
+
elsif after.start_with?('[]')
|
173
|
+
# Recognize x[][y] (hash inside array) parameters
|
174
|
+
unless after[2] == '[' && after.end_with?(']') && (child_key = after[3, after.length-4]) && !child_key.empty? && !child_key.index('[') && !child_key.index(']')
|
175
|
+
# Handle other nested array parameters
|
176
|
+
child_key = after[2, after.length]
|
177
|
+
end
|
139
178
|
params[k] ||= []
|
140
179
|
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
141
180
|
if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
|
142
|
-
|
181
|
+
_normalize_params(params[k].last, child_key, v, depth + 1)
|
143
182
|
else
|
144
|
-
params[k] <<
|
183
|
+
params[k] << _normalize_params(make_params, child_key, v, depth + 1)
|
145
184
|
end
|
146
185
|
else
|
147
186
|
params[k] ||= make_params
|
148
187
|
raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
|
149
|
-
params[k] =
|
188
|
+
params[k] = _normalize_params(params[k], after, v, depth + 1)
|
150
189
|
end
|
151
190
|
|
152
191
|
params
|
153
192
|
end
|
154
193
|
|
155
194
|
def make_params
|
156
|
-
@params_class.new
|
157
|
-
end
|
158
|
-
|
159
|
-
def new_space_limit(key_space_limit)
|
160
|
-
self.class.new @params_class, key_space_limit, param_depth_limit
|
195
|
+
@params_class.new
|
161
196
|
end
|
162
197
|
|
163
198
|
def new_depth_limit(param_depth_limit)
|
164
|
-
self.class.new @params_class,
|
199
|
+
self.class.new @params_class, param_depth_limit
|
165
200
|
end
|
166
201
|
|
167
202
|
private
|
@@ -198,13 +233,12 @@ module Rack
|
|
198
233
|
end
|
199
234
|
end
|
200
235
|
|
201
|
-
def unescape(string)
|
202
|
-
|
236
|
+
def unescape(string, encoding = Encoding::UTF_8)
|
237
|
+
URI.decode_www_form_component(string, encoding)
|
203
238
|
end
|
204
239
|
|
205
240
|
class Params
|
206
|
-
def initialize
|
207
|
-
@limit = limit
|
241
|
+
def initialize
|
208
242
|
@size = 0
|
209
243
|
@params = {}
|
210
244
|
end
|
@@ -214,8 +248,6 @@ module Rack
|
|
214
248
|
end
|
215
249
|
|
216
250
|
def []=(key, value)
|
217
|
-
@size += key.size if key && !@params.key?(key)
|
218
|
-
raise ParamsTooDeepError, 'exceeded available parameter key space' if @size > @limit
|
219
251
|
@params[key] = value
|
220
252
|
end
|
221
253
|
|
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
|