rack 2.2.4 → 3.0.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +223 -71
- data/CONTRIBUTING.md +53 -47
- data/MIT-LICENSE +1 -1
- data/README.md +309 -0
- data/SPEC.rdoc +183 -131
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +3 -1
- data/lib/rack/auth/basic.rb +0 -2
- data/lib/rack/auth/digest/md5.rb +1 -131
- data/lib/rack/auth/digest/nonce.rb +1 -54
- 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 +83 -63
- data/lib/rack/cascade.rb +2 -0
- data/lib/rack/chunked.rb +16 -13
- data/lib/rack/common_logger.rb +23 -18
- 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 +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 +783 -682
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +1 -1
- data/lib/rack/method_override.rb +6 -2
- data/lib/rack/mime.rb +8 -0
- data/lib/rack/mock.rb +1 -271
- data/lib/rack/mock_request.rb +166 -0
- data/lib/rack/mock_response.rb +126 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +134 -65
- 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 +226 -108
- data/lib/rack/response.rb +136 -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 +4 -2
- data/lib/rack/utils.rb +223 -185
- data/lib/rack/version.rb +9 -4
- data/lib/rack.rb +6 -76
- metadata +18 -38
- data/README.rdoc +0 -306
- 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 -85
- 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
|
@@ -20,29 +20,35 @@ module Rack
|
|
20
20
|
# nested over the specified limit.
|
21
21
|
class ParamsTooDeepError < RangeError; end
|
22
22
|
|
23
|
-
def self.make_default(
|
24
|
-
|
23
|
+
def self.make_default(_key_space_limit=(not_deprecated = true; nil), param_depth_limit)
|
24
|
+
unless not_deprecated
|
25
|
+
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)
|
26
|
+
end
|
27
|
+
|
28
|
+
new Params, param_depth_limit
|
25
29
|
end
|
26
30
|
|
27
|
-
attr_reader :
|
31
|
+
attr_reader :param_depth_limit
|
32
|
+
|
33
|
+
def initialize(params_class, _key_space_limit=(not_deprecated = true; nil), param_depth_limit)
|
34
|
+
unless not_deprecated
|
35
|
+
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)
|
36
|
+
end
|
28
37
|
|
29
|
-
def initialize(params_class, key_space_limit, param_depth_limit)
|
30
38
|
@params_class = params_class
|
31
|
-
@key_space_limit = key_space_limit
|
32
39
|
@param_depth_limit = param_depth_limit
|
33
40
|
end
|
34
41
|
|
35
42
|
# Stolen from Mongrel, with some small modifications:
|
36
|
-
# Parses a query string by breaking it up at the '&'
|
37
|
-
#
|
38
|
-
#
|
39
|
-
|
40
|
-
def parse_query(qs, d = nil, &unescaper)
|
43
|
+
# Parses a query string by breaking it up at the '&'. You can also use this
|
44
|
+
# to parse cookies by changing the characters used in the second parameter
|
45
|
+
# (which defaults to '&').
|
46
|
+
def parse_query(qs, separator = nil, &unescaper)
|
41
47
|
unescaper ||= method(:unescape)
|
42
48
|
|
43
49
|
params = make_params
|
44
50
|
|
45
|
-
(qs || '').split(
|
51
|
+
(qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
|
46
52
|
next if p.empty?
|
47
53
|
k, v = p.split('=', 2).map!(&unescaper)
|
48
54
|
|
@@ -65,14 +71,14 @@ module Rack
|
|
65
71
|
# query strings with parameters of conflicting types, in this case a
|
66
72
|
# ParameterTypeError is raised. Users are encouraged to return a 400 in this
|
67
73
|
# case.
|
68
|
-
def parse_nested_query(qs,
|
74
|
+
def parse_nested_query(qs, separator = nil)
|
69
75
|
params = make_params
|
70
76
|
|
71
77
|
unless qs.nil? || qs.empty?
|
72
|
-
(qs || '').split(
|
78
|
+
(qs || '').split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p|
|
73
79
|
k, v = p.split('=', 2).map! { |s| unescape(s) }
|
74
80
|
|
75
|
-
|
81
|
+
_normalize_params(params, k, v, 0)
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
@@ -83,58 +89,87 @@ module Rack
|
|
83
89
|
|
84
90
|
# normalize_params recursively expands parameters into structural types. If
|
85
91
|
# the structural types represented by two different parameter names are in
|
86
|
-
# conflict, a ParameterTypeError is raised.
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
name
|
91
|
-
|
92
|
-
after = $' || ''
|
92
|
+
# conflict, a ParameterTypeError is raised. The depth argument is deprecated
|
93
|
+
# and should no longer be used, it is kept for backwards compatibility with
|
94
|
+
# earlier versions of rack.
|
95
|
+
def normalize_params(params, name, v, _depth=nil)
|
96
|
+
_normalize_params(params, name, v, 0)
|
97
|
+
end
|
93
98
|
|
94
|
-
|
95
|
-
|
96
|
-
|
99
|
+
private def _normalize_params(params, name, v, depth)
|
100
|
+
raise ParamsTooDeepError if depth >= param_depth_limit
|
101
|
+
|
102
|
+
if !name
|
103
|
+
# nil name, treat same as empty string (required by tests)
|
104
|
+
k = after = ''
|
105
|
+
elsif depth == 0
|
106
|
+
# Start of parsing, don't treat [] or [ at start of string specially
|
107
|
+
if start = name.index('[', 1)
|
108
|
+
# Start of parameter nesting, use part before brackets as key
|
109
|
+
k = name[0, start]
|
110
|
+
after = name[start, name.length]
|
97
111
|
else
|
98
|
-
|
112
|
+
# Plain parameter with no nesting
|
113
|
+
k = name
|
114
|
+
after = ''
|
99
115
|
end
|
116
|
+
elsif name.start_with?('[]')
|
117
|
+
# Array nesting
|
118
|
+
k = '[]'
|
119
|
+
after = name[2, name.length]
|
120
|
+
elsif name.start_with?('[') && (start = name.index(']', 1))
|
121
|
+
# Hash nesting, use the part inside brackets as the key
|
122
|
+
k = name[1, start-1]
|
123
|
+
after = name[start+1, name.length]
|
124
|
+
else
|
125
|
+
# Probably malformed input, nested but not starting with [
|
126
|
+
# treat full name as key for backwards compatibility.
|
127
|
+
k = name
|
128
|
+
after = ''
|
100
129
|
end
|
101
130
|
|
131
|
+
return if k.empty?
|
132
|
+
|
102
133
|
if after == ''
|
103
|
-
|
134
|
+
if k == '[]' && depth != 0
|
135
|
+
return [v]
|
136
|
+
else
|
137
|
+
params[k] = v
|
138
|
+
end
|
104
139
|
elsif after == "["
|
105
140
|
params[name] = v
|
106
141
|
elsif after == "[]"
|
107
142
|
params[k] ||= []
|
108
143
|
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
109
144
|
params[k] << v
|
110
|
-
elsif after
|
111
|
-
|
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
|
112
151
|
params[k] ||= []
|
113
152
|
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
114
153
|
if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
|
115
|
-
|
154
|
+
_normalize_params(params[k].last, child_key, v, depth + 1)
|
116
155
|
else
|
117
|
-
params[k] <<
|
156
|
+
params[k] << _normalize_params(make_params, child_key, v, depth + 1)
|
118
157
|
end
|
119
158
|
else
|
120
159
|
params[k] ||= make_params
|
121
160
|
raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
|
122
|
-
params[k] =
|
161
|
+
params[k] = _normalize_params(params[k], after, v, depth + 1)
|
123
162
|
end
|
124
163
|
|
125
164
|
params
|
126
165
|
end
|
127
166
|
|
128
167
|
def make_params
|
129
|
-
@params_class.new
|
130
|
-
end
|
131
|
-
|
132
|
-
def new_space_limit(key_space_limit)
|
133
|
-
self.class.new @params_class, key_space_limit, param_depth_limit
|
168
|
+
@params_class.new
|
134
169
|
end
|
135
170
|
|
136
171
|
def new_depth_limit(param_depth_limit)
|
137
|
-
self.class.new @params_class,
|
172
|
+
self.class.new @params_class, param_depth_limit
|
138
173
|
end
|
139
174
|
|
140
175
|
private
|
@@ -155,13 +190,12 @@ module Rack
|
|
155
190
|
true
|
156
191
|
end
|
157
192
|
|
158
|
-
def unescape(
|
159
|
-
|
193
|
+
def unescape(string, encoding = Encoding::UTF_8)
|
194
|
+
URI.decode_www_form_component(string, encoding)
|
160
195
|
end
|
161
196
|
|
162
197
|
class Params
|
163
|
-
def initialize
|
164
|
-
@limit = limit
|
198
|
+
def initialize
|
165
199
|
@size = 0
|
166
200
|
@params = {}
|
167
201
|
end
|
@@ -171,8 +205,6 @@ module Rack
|
|
171
205
|
end
|
172
206
|
|
173
207
|
def []=(key, value)
|
174
|
-
@size += key.size if key && !@params.key?(key)
|
175
|
-
raise ParamsTooDeepError, 'exceeded available parameter key space' if @size > @limit
|
176
208
|
@params[key] = value
|
177
209
|
end
|
178
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
|