rack 1.6.13 → 2.1.4.3

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.

Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +92 -0
  3. data/{COPYING → MIT-LICENSE} +4 -2
  4. data/README.rdoc +105 -141
  5. data/Rakefile +27 -28
  6. data/SPEC +6 -7
  7. data/bin/rackup +1 -0
  8. data/contrib/rack_logo.svg +164 -111
  9. data/example/lobster.ru +2 -0
  10. data/example/protectedlobster.rb +4 -2
  11. data/example/protectedlobster.ru +3 -1
  12. data/lib/rack/auth/abstract/handler.rb +3 -1
  13. data/lib/rack/auth/abstract/request.rb +7 -1
  14. data/lib/rack/auth/basic.rb +4 -1
  15. data/lib/rack/auth/digest/md5.rb +9 -7
  16. data/lib/rack/auth/digest/nonce.rb +6 -3
  17. data/lib/rack/auth/digest/params.rb +5 -4
  18. data/lib/rack/auth/digest/request.rb +3 -1
  19. data/lib/rack/body_proxy.rb +11 -9
  20. data/lib/rack/builder.rb +42 -18
  21. data/lib/rack/cascade.rb +6 -5
  22. data/lib/rack/chunked.rb +33 -10
  23. data/lib/rack/{commonlogger.rb → common_logger.rb} +14 -10
  24. data/lib/rack/{conditionalget.rb → conditional_get.rb} +3 -1
  25. data/lib/rack/config.rb +2 -0
  26. data/lib/rack/content_length.rb +5 -3
  27. data/lib/rack/content_type.rb +3 -1
  28. data/lib/rack/core_ext/regexp.rb +14 -0
  29. data/lib/rack/deflater.rb +33 -53
  30. data/lib/rack/directory.rb +75 -60
  31. data/lib/rack/etag.rb +8 -5
  32. data/lib/rack/events.rb +156 -0
  33. data/lib/rack/file.rb +4 -149
  34. data/lib/rack/files.rb +178 -0
  35. data/lib/rack/handler/cgi.rb +18 -17
  36. data/lib/rack/handler/fastcgi.rb +17 -16
  37. data/lib/rack/handler/lsws.rb +14 -12
  38. data/lib/rack/handler/scgi.rb +22 -19
  39. data/lib/rack/handler/thin.rb +6 -1
  40. data/lib/rack/handler/webrick.rb +28 -28
  41. data/lib/rack/handler.rb +9 -26
  42. data/lib/rack/head.rb +17 -17
  43. data/lib/rack/lint.rb +55 -52
  44. data/lib/rack/lobster.rb +8 -6
  45. data/lib/rack/lock.rb +17 -10
  46. data/lib/rack/logger.rb +4 -2
  47. data/lib/rack/media_type.rb +43 -0
  48. data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
  49. data/lib/rack/mime.rb +27 -6
  50. data/lib/rack/mock.rb +101 -60
  51. data/lib/rack/multipart/generator.rb +11 -12
  52. data/lib/rack/multipart/parser.rb +292 -161
  53. data/lib/rack/multipart/uploaded_file.rb +3 -2
  54. data/lib/rack/multipart.rb +38 -8
  55. data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
  56. data/lib/rack/query_parser.rb +218 -0
  57. data/lib/rack/recursive.rb +11 -9
  58. data/lib/rack/reloader.rb +10 -4
  59. data/lib/rack/request.rb +447 -305
  60. data/lib/rack/response.rb +196 -83
  61. data/lib/rack/rewindable_input.rb +5 -14
  62. data/lib/rack/runtime.rb +12 -18
  63. data/lib/rack/sendfile.rb +19 -14
  64. data/lib/rack/server.rb +118 -41
  65. data/lib/rack/session/abstract/id.rb +139 -94
  66. data/lib/rack/session/cookie.rb +34 -26
  67. data/lib/rack/session/memcache.rb +4 -93
  68. data/lib/rack/session/pool.rb +12 -10
  69. data/lib/rack/show_exceptions.rb +392 -0
  70. data/lib/rack/{showstatus.rb → show_status.rb} +7 -5
  71. data/lib/rack/static.rb +41 -11
  72. data/lib/rack/tempfile_reaper.rb +4 -2
  73. data/lib/rack/urlmap.rb +25 -15
  74. data/lib/rack/utils.rb +203 -277
  75. data/lib/rack.rb +76 -24
  76. data/rack.gemspec +25 -14
  77. metadata +62 -183
  78. data/HISTORY.md +0 -375
  79. data/KNOWN-ISSUES +0 -44
  80. data/lib/rack/backports/uri/common_18.rb +0 -56
  81. data/lib/rack/backports/uri/common_192.rb +0 -52
  82. data/lib/rack/backports/uri/common_193.rb +0 -29
  83. data/lib/rack/handler/evented_mongrel.rb +0 -8
  84. data/lib/rack/handler/mongrel.rb +0 -106
  85. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  86. data/lib/rack/showexceptions.rb +0 -387
  87. data/lib/rack/utils/okjson.rb +0 -600
  88. data/test/builder/anything.rb +0 -5
  89. data/test/builder/comment.ru +0 -4
  90. data/test/builder/end.ru +0 -5
  91. data/test/builder/line.ru +0 -1
  92. data/test/builder/options.ru +0 -2
  93. data/test/cgi/assets/folder/test.js +0 -1
  94. data/test/cgi/assets/fonts/font.eot +0 -1
  95. data/test/cgi/assets/images/image.png +0 -1
  96. data/test/cgi/assets/index.html +0 -1
  97. data/test/cgi/assets/javascripts/app.js +0 -1
  98. data/test/cgi/assets/stylesheets/app.css +0 -1
  99. data/test/cgi/lighttpd.conf +0 -26
  100. data/test/cgi/rackup_stub.rb +0 -6
  101. data/test/cgi/sample_rackup.ru +0 -5
  102. data/test/cgi/test +0 -9
  103. data/test/cgi/test+directory/test+file +0 -1
  104. data/test/cgi/test.fcgi +0 -8
  105. data/test/cgi/test.ru +0 -5
  106. data/test/gemloader.rb +0 -10
  107. data/test/multipart/bad_robots +0 -259
  108. data/test/multipart/binary +0 -0
  109. data/test/multipart/content_type_and_no_filename +0 -6
  110. data/test/multipart/empty +0 -10
  111. data/test/multipart/fail_16384_nofile +0 -814
  112. data/test/multipart/file1.txt +0 -1
  113. data/test/multipart/filename_and_modification_param +0 -7
  114. data/test/multipart/filename_and_no_name +0 -6
  115. data/test/multipart/filename_with_escaped_quotes +0 -6
  116. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  117. data/test/multipart/filename_with_null_byte +0 -7
  118. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  119. data/test/multipart/filename_with_unescaped_percentages +0 -6
  120. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  121. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  122. data/test/multipart/filename_with_unescaped_quotes +0 -6
  123. data/test/multipart/ie +0 -6
  124. data/test/multipart/invalid_character +0 -6
  125. data/test/multipart/mixed_files +0 -21
  126. data/test/multipart/nested +0 -10
  127. data/test/multipart/none +0 -9
  128. data/test/multipart/semicolon +0 -6
  129. data/test/multipart/text +0 -15
  130. data/test/multipart/three_files_three_fields +0 -31
  131. data/test/multipart/webkit +0 -32
  132. data/test/rackup/config.ru +0 -31
  133. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  134. data/test/spec_auth_basic.rb +0 -81
  135. data/test/spec_auth_digest.rb +0 -259
  136. data/test/spec_body_proxy.rb +0 -85
  137. data/test/spec_builder.rb +0 -223
  138. data/test/spec_cascade.rb +0 -61
  139. data/test/spec_cgi.rb +0 -102
  140. data/test/spec_chunked.rb +0 -101
  141. data/test/spec_commonlogger.rb +0 -93
  142. data/test/spec_conditionalget.rb +0 -102
  143. data/test/spec_config.rb +0 -22
  144. data/test/spec_content_length.rb +0 -85
  145. data/test/spec_content_type.rb +0 -45
  146. data/test/spec_deflater.rb +0 -339
  147. data/test/spec_directory.rb +0 -88
  148. data/test/spec_etag.rb +0 -107
  149. data/test/spec_fastcgi.rb +0 -107
  150. data/test/spec_file.rb +0 -221
  151. data/test/spec_handler.rb +0 -72
  152. data/test/spec_head.rb +0 -45
  153. data/test/spec_lint.rb +0 -550
  154. data/test/spec_lobster.rb +0 -58
  155. data/test/spec_lock.rb +0 -164
  156. data/test/spec_logger.rb +0 -23
  157. data/test/spec_methodoverride.rb +0 -111
  158. data/test/spec_mime.rb +0 -51
  159. data/test/spec_mock.rb +0 -297
  160. data/test/spec_mongrel.rb +0 -182
  161. data/test/spec_multipart.rb +0 -600
  162. data/test/spec_nulllogger.rb +0 -20
  163. data/test/spec_recursive.rb +0 -72
  164. data/test/spec_request.rb +0 -1232
  165. data/test/spec_response.rb +0 -407
  166. data/test/spec_rewindable_input.rb +0 -118
  167. data/test/spec_runtime.rb +0 -49
  168. data/test/spec_sendfile.rb +0 -130
  169. data/test/spec_server.rb +0 -167
  170. data/test/spec_session_abstract_id.rb +0 -53
  171. data/test/spec_session_cookie.rb +0 -410
  172. data/test/spec_session_memcache.rb +0 -358
  173. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  174. data/test/spec_session_pool.rb +0 -246
  175. data/test/spec_showexceptions.rb +0 -98
  176. data/test/spec_showstatus.rb +0 -103
  177. data/test/spec_static.rb +0 -145
  178. data/test/spec_tempfile_reaper.rb +0 -63
  179. data/test/spec_thin.rb +0 -91
  180. data/test/spec_urlmap.rb +0 -236
  181. data/test/spec_utils.rb +0 -647
  182. data/test/spec_version.rb +0 -17
  183. data/test/spec_webrick.rb +0 -184
  184. data/test/static/another/index.html +0 -1
  185. data/test/static/index.html +0 -1
  186. data/test/testrequest.rb +0 -78
  187. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  188. data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'core_ext/regexp'
4
+
5
+ module Rack
6
+ class QueryParser
7
+ using ::Rack::RegexpExtensions
8
+
9
+ DEFAULT_SEP = /[&;] */n
10
+ COMMON_SEP = { ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }
11
+
12
+ # ParameterTypeError is the error that is raised when incoming structural
13
+ # parameters (parsed by parse_nested_query) contain conflicting types.
14
+ class ParameterTypeError < TypeError; end
15
+
16
+ # InvalidParameterError is the error that is raised when incoming structural
17
+ # parameters (parsed by parse_nested_query) contain invalid format or byte
18
+ # sequence.
19
+ class InvalidParameterError < ArgumentError; end
20
+
21
+ def self.make_default(key_space_limit, param_depth_limit)
22
+ new Params, key_space_limit, param_depth_limit
23
+ end
24
+
25
+ attr_reader :key_space_limit, :param_depth_limit
26
+
27
+ def initialize(params_class, key_space_limit, param_depth_limit)
28
+ @params_class = params_class
29
+ @key_space_limit = key_space_limit
30
+ @param_depth_limit = param_depth_limit
31
+ end
32
+
33
+ # Stolen from Mongrel, with some small modifications:
34
+ # Parses a query string by breaking it up at the '&'
35
+ # and ';' characters. You can also use this to parse
36
+ # cookies by changing the characters used in the second
37
+ # parameter (which defaults to '&;').
38
+ def parse_query(qs, d = nil, &unescaper)
39
+ unescaper ||= method(:unescape)
40
+
41
+ params = make_params
42
+
43
+ (qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
44
+ next if p.empty?
45
+ k, v = p.split('=', 2).map!(&unescaper)
46
+
47
+ if cur = params[k]
48
+ if cur.class == Array
49
+ params[k] << v
50
+ else
51
+ params[k] = [cur, v]
52
+ end
53
+ else
54
+ params[k] = v
55
+ end
56
+ end
57
+
58
+ return params.to_h
59
+ end
60
+
61
+ # parse_nested_query expands a query string into structural types. Supported
62
+ # types are Arrays, Hashes and basic value types. It is possible to supply
63
+ # query strings with parameters of conflicting types, in this case a
64
+ # ParameterTypeError is raised. Users are encouraged to return a 400 in this
65
+ # case.
66
+ def parse_nested_query(qs, d = nil)
67
+ return {} if qs.nil? || qs.empty?
68
+ params = make_params
69
+
70
+ qs.split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
71
+ k, v = p.split('=', 2).map! { |s| unescape(s) }
72
+
73
+ normalize_params(params, k, v, param_depth_limit)
74
+ end
75
+
76
+ return params.to_h
77
+ rescue ArgumentError => e
78
+ raise InvalidParameterError, e.message
79
+ end
80
+
81
+ # normalize_params recursively expands parameters into structural types. If
82
+ # the structural types represented by two different parameter names are in
83
+ # conflict, a ParameterTypeError is raised.
84
+ def normalize_params(params, name, v, depth)
85
+ raise RangeError if depth <= 0
86
+
87
+ name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
88
+ k = $1 || ''
89
+ after = $' || ''
90
+
91
+ if k.empty?
92
+ if !v.nil? && name == "[]"
93
+ return Array(v)
94
+ else
95
+ return
96
+ end
97
+ end
98
+
99
+ if after == ''
100
+ params[k] = v
101
+ elsif after == "["
102
+ params[name] = v
103
+ elsif after == "[]"
104
+ params[k] ||= []
105
+ raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
106
+ params[k] << v
107
+ elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
108
+ child_key = $1
109
+ params[k] ||= []
110
+ raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
111
+ if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
112
+ normalize_params(params[k].last, child_key, v, depth - 1)
113
+ else
114
+ params[k] << normalize_params(make_params, child_key, v, depth - 1)
115
+ end
116
+ else
117
+ params[k] ||= make_params
118
+ raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
119
+ params[k] = normalize_params(params[k], after, v, depth - 1)
120
+ end
121
+
122
+ params
123
+ end
124
+
125
+ def make_params
126
+ @params_class.new @key_space_limit
127
+ end
128
+
129
+ def new_space_limit(key_space_limit)
130
+ self.class.new @params_class, key_space_limit, param_depth_limit
131
+ end
132
+
133
+ def new_depth_limit(param_depth_limit)
134
+ self.class.new @params_class, key_space_limit, param_depth_limit
135
+ end
136
+
137
+ private
138
+
139
+ def params_hash_type?(obj)
140
+ obj.kind_of?(@params_class)
141
+ end
142
+
143
+ def params_hash_has_key?(hash, key)
144
+ return false if /\[\]/.match?(key)
145
+
146
+ key.split(/[\[\]]+/).inject(hash) do |h, part|
147
+ next h if part == ''
148
+ return false unless params_hash_type?(h) && h.key?(part)
149
+ h[part]
150
+ end
151
+
152
+ true
153
+ end
154
+
155
+ def unescape(s)
156
+ Utils.unescape(s)
157
+ end
158
+
159
+ class Params
160
+ def initialize(limit)
161
+ @limit = limit
162
+ @size = 0
163
+ @params = {}
164
+ end
165
+
166
+ def [](key)
167
+ @params[key]
168
+ end
169
+
170
+ def []=(key, value)
171
+ @size += key.size if key && !@params.key?(key)
172
+ raise RangeError, 'exceeded available parameter key space' if @size > @limit
173
+ @params[key] = value
174
+ end
175
+
176
+ def key?(key)
177
+ @params.key?(key)
178
+ end
179
+
180
+ # Recursively unwraps nested `Params` objects and constructs an object
181
+ # of the same shape, but using the objects' internal representations
182
+ # (Ruby hashes) in place of the objects. The result is a hash consisting
183
+ # purely of Ruby primitives.
184
+ #
185
+ # Mutation warning!
186
+ #
187
+ # 1. This method mutates the internal representation of the `Params`
188
+ # objects in order to save object allocations.
189
+ #
190
+ # 2. The value you get back is a reference to the internal hash
191
+ # representation, not a copy.
192
+ #
193
+ # 3. Because the `Params` object's internal representation is mutable
194
+ # through the `#[]=` method, it is not thread safe. The result of
195
+ # getting the hash representation while another thread is adding a
196
+ # key to it is non-deterministic.
197
+ #
198
+ def to_h
199
+ @params.each do |key, value|
200
+ case value
201
+ when self
202
+ # Handle circular references gracefully.
203
+ @params[key] = @params
204
+ when Params
205
+ @params[key] = value.to_h
206
+ when Array
207
+ value.map! { |v| v.kind_of?(Params) ? v.to_h : v }
208
+ else
209
+ # Ignore anything that is not a `Params` object or
210
+ # a collection that can contain one.
211
+ end
212
+ end
213
+ @params
214
+ end
215
+ alias_method :to_params_hash, :to_h
216
+ end
217
+ end
218
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
 
3
5
  module Rack
@@ -10,15 +12,15 @@ module Rack
10
12
  class ForwardRequest < Exception
11
13
  attr_reader :url, :env
12
14
 
13
- def initialize(url, env={})
15
+ def initialize(url, env = {})
14
16
  @url = URI(url)
15
17
  @env = env
16
18
 
17
- @env[PATH_INFO] = @url.path
18
- @env[QUERY_STRING] = @url.query if @url.query
19
- @env["HTTP_HOST"] = @url.host if @url.host
20
- @env["HTTP_PORT"] = @url.port if @url.port
21
- @env["rack.url_scheme"] = @url.scheme if @url.scheme
19
+ @env[PATH_INFO] = @url.path
20
+ @env[QUERY_STRING] = @url.query if @url.query
21
+ @env[HTTP_HOST] = @url.host if @url.host
22
+ @env["HTTP_PORT"] = @url.port if @url.port
23
+ @env[RACK_URL_SCHEME] = @url.scheme if @url.scheme
22
24
 
23
25
  super "forwarding to #{url}"
24
26
  end
@@ -40,7 +42,7 @@ module Rack
40
42
 
41
43
  def _call(env)
42
44
  @script_name = env[SCRIPT_NAME]
43
- @app.call(env.merge('rack.recursive.include' => method(:include)))
45
+ @app.call(env.merge(RACK_RECURSIVE_INCLUDE => method(:include)))
44
46
  rescue ForwardRequest => req
45
47
  call(env.merge(req.env))
46
48
  end
@@ -53,9 +55,9 @@ module Rack
53
55
 
54
56
  env = env.merge(PATH_INFO => path,
55
57
  SCRIPT_NAME => @script_name,
56
- REQUEST_METHOD => "GET",
58
+ REQUEST_METHOD => GET,
57
59
  "CONTENT_LENGTH" => "0", "CONTENT_TYPE" => "",
58
- "rack.input" => StringIO.new(""))
60
+ RACK_INPUT => StringIO.new(""))
59
61
  @app.call(env)
60
62
  end
61
63
  end
data/lib/rack/reloader.rb CHANGED
@@ -1,9 +1,13 @@
1
- # Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
2
- # Rack::Reloader is subject to the terms of an MIT-style license.
3
- # See COPYING or http://www.opensource.org/licenses/mit-license.php.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2009-2018 Michael Fellinger <m.fellinger@gmail.com>
4
+ # Rack::Reloader is subject to the terms of an MIT-style license.
5
+ # See MIT-LICENSE or https://opensource.org/licenses/MIT.
4
6
 
5
7
  require 'pathname'
6
8
 
9
+ require_relative 'core_ext/regexp'
10
+
7
11
  module Rack
8
12
 
9
13
  # High performant source reloader
@@ -20,6 +24,8 @@ module Rack
20
24
  # It is performing a check/reload cycle at the start of every request, but
21
25
  # also respects a cool down time, during which nothing will be done.
22
26
  class Reloader
27
+ using ::Rack::RegexpExtensions
28
+
23
29
  def initialize(app, cooldown = 10, backend = Stat)
24
30
  @app = app
25
31
  @cooldown = cooldown
@@ -69,7 +75,7 @@ module Rack
69
75
  paths = ['./', *$LOAD_PATH].uniq
70
76
 
71
77
  files.map{|file|
72
- next if file =~ /\.(so|bundle)$/ # cannot reload compiled files
78
+ next if /\.(so|bundle)$/.match?(file) # cannot reload compiled files
73
79
 
74
80
  found, stat = figure_path(file, paths)
75
81
  next unless found && stat && mtime = stat.mtime