rack 2.1.4.4 → 2.2.0

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +598 -15
  3. data/CONTRIBUTING.md +136 -0
  4. data/README.rdoc +84 -54
  5. data/Rakefile +14 -7
  6. data/{SPEC → SPEC.rdoc} +35 -6
  7. data/lib/rack/auth/abstract/request.rb +0 -2
  8. data/lib/rack/auth/basic.rb +3 -3
  9. data/lib/rack/auth/digest/md5.rb +4 -4
  10. data/lib/rack/auth/digest/request.rb +3 -3
  11. data/lib/rack/body_proxy.rb +13 -9
  12. data/lib/rack/builder.rb +77 -8
  13. data/lib/rack/cascade.rb +23 -8
  14. data/lib/rack/chunked.rb +48 -23
  15. data/lib/rack/common_logger.rb +25 -21
  16. data/lib/rack/conditional_get.rb +18 -16
  17. data/lib/rack/content_length.rb +6 -7
  18. data/lib/rack/content_type.rb +3 -4
  19. data/lib/rack/deflater.rb +45 -35
  20. data/lib/rack/directory.rb +77 -60
  21. data/lib/rack/etag.rb +2 -3
  22. data/lib/rack/events.rb +15 -18
  23. data/lib/rack/file.rb +1 -1
  24. data/lib/rack/files.rb +96 -56
  25. data/lib/rack/handler/cgi.rb +1 -4
  26. data/lib/rack/handler/fastcgi.rb +1 -3
  27. data/lib/rack/handler/lsws.rb +1 -3
  28. data/lib/rack/handler/scgi.rb +1 -3
  29. data/lib/rack/handler/thin.rb +15 -11
  30. data/lib/rack/handler/webrick.rb +12 -5
  31. data/lib/rack/head.rb +0 -2
  32. data/lib/rack/lint.rb +58 -15
  33. data/lib/rack/lobster.rb +3 -5
  34. data/lib/rack/lock.rb +0 -1
  35. data/lib/rack/mock.rb +22 -4
  36. data/lib/rack/multipart/generator.rb +11 -6
  37. data/lib/rack/multipart/parser.rb +12 -32
  38. data/lib/rack/multipart/uploaded_file.rb +13 -7
  39. data/lib/rack/multipart.rb +5 -4
  40. data/lib/rack/query_parser.rb +7 -8
  41. data/lib/rack/recursive.rb +1 -1
  42. data/lib/rack/reloader.rb +1 -3
  43. data/lib/rack/request.rb +172 -76
  44. data/lib/rack/response.rb +62 -19
  45. data/lib/rack/rewindable_input.rb +0 -1
  46. data/lib/rack/runtime.rb +3 -3
  47. data/lib/rack/sendfile.rb +0 -3
  48. data/lib/rack/server.rb +9 -8
  49. data/lib/rack/session/abstract/id.rb +20 -18
  50. data/lib/rack/session/cookie.rb +2 -3
  51. data/lib/rack/session/pool.rb +1 -1
  52. data/lib/rack/show_exceptions.rb +2 -4
  53. data/lib/rack/show_status.rb +1 -3
  54. data/lib/rack/static.rb +13 -6
  55. data/lib/rack/tempfile_reaper.rb +0 -2
  56. data/lib/rack/urlmap.rb +1 -4
  57. data/lib/rack/utils.rb +70 -82
  58. data/lib/rack/version.rb +29 -0
  59. data/lib/rack.rb +7 -16
  60. data/rack.gemspec +31 -29
  61. metadata +14 -15
data/lib/rack/utils.rb CHANGED
@@ -5,17 +5,16 @@ require 'uri'
5
5
  require 'fileutils'
6
6
  require 'set'
7
7
  require 'tempfile'
8
- require 'rack/query_parser'
9
8
  require 'time'
10
9
 
11
- require_relative 'core_ext/regexp'
10
+ require_relative 'query_parser'
12
11
 
13
12
  module Rack
14
13
  # Rack::Utils contains a grab-bag of useful methods for writing web
15
14
  # applications adopted from all kinds of Ruby libraries.
16
15
 
17
16
  module Utils
18
- using ::Rack::RegexpExtensions
17
+ (require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
19
18
 
20
19
  ParameterTypeError = QueryParser::ParameterTypeError
21
20
  InvalidParameterError = QueryParser::InvalidParameterError
@@ -30,53 +29,39 @@ module Rack
30
29
  # This helps prevent a rogue client from flooding a Request.
31
30
  self.default_query_parser = QueryParser.make_default(65536, 100)
32
31
 
32
+ module_function
33
+
33
34
  # URI escapes. (CGI style space to +)
34
35
  def escape(s)
35
36
  URI.encode_www_form_component(s)
36
37
  end
37
- module_function :escape
38
38
 
39
39
  # Like URI escaping, but with %20 instead of +. Strictly speaking this is
40
40
  # true URI escaping.
41
41
  def escape_path(s)
42
42
  ::URI::DEFAULT_PARSER.escape s
43
43
  end
44
- module_function :escape_path
45
44
 
46
45
  # Unescapes the **path** component of a URI. See Rack::Utils.unescape for
47
46
  # unescaping query parameters or form components.
48
47
  def unescape_path(s)
49
48
  ::URI::DEFAULT_PARSER.unescape s
50
49
  end
51
- module_function :unescape_path
52
-
53
50
 
54
51
  # Unescapes a URI escaped string with +encoding+. +encoding+ will be the
55
52
  # target encoding of the string returned, and it defaults to UTF-8
56
53
  def unescape(s, encoding = Encoding::UTF_8)
57
54
  URI.decode_www_form_component(s, encoding)
58
55
  end
59
- module_function :unescape
60
56
 
61
57
  class << self
62
- attr_accessor :multipart_total_part_limit
63
-
64
- attr_accessor :multipart_file_limit
65
-
66
- # multipart_part_limit is the original name of multipart_file_limit, but
67
- # the limit only counts parts with filenames.
68
- alias multipart_part_limit multipart_file_limit
69
- alias multipart_part_limit= multipart_file_limit=
58
+ attr_accessor :multipart_part_limit
70
59
  end
71
60
 
72
- # The maximum number of file parts a request can contain. Accepting too
73
- # many parts can lead to the server running out of file handles.
61
+ # The maximum number of parts a request can contain. Accepting too many part
62
+ # can lead to the server running out of file handles.
74
63
  # Set to `0` for no limit.
75
- self.multipart_file_limit = (ENV['RACK_MULTIPART_PART_LIMIT'] || ENV['RACK_MULTIPART_FILE_LIMIT'] || 128).to_i
76
-
77
- # The maximum total number of parts a request can contain. Accepting too
78
- # many can lead to excessive memory use and parsing time.
79
- self.multipart_total_part_limit = (ENV['RACK_MULTIPART_TOTAL_PART_LIMIT'] || 4096).to_i
64
+ self.multipart_part_limit = (ENV['RACK_MULTIPART_PART_LIMIT'] || 128).to_i
80
65
 
81
66
  def self.param_depth_limit
82
67
  default_query_parser.param_depth_limit
@@ -99,21 +84,20 @@ module Rack
99
84
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
100
85
  end
101
86
  else
87
+ # :nocov:
102
88
  def clock_time
103
89
  Time.now.to_f
104
90
  end
91
+ # :nocov:
105
92
  end
106
- module_function :clock_time
107
93
 
108
94
  def parse_query(qs, d = nil, &unescaper)
109
95
  Rack::Utils.default_query_parser.parse_query(qs, d, &unescaper)
110
96
  end
111
- module_function :parse_query
112
97
 
113
98
  def parse_nested_query(qs, d = nil)
114
99
  Rack::Utils.default_query_parser.parse_nested_query(qs, d)
115
100
  end
116
- module_function :parse_nested_query
117
101
 
118
102
  def build_query(params)
119
103
  params.map { |k, v|
@@ -124,7 +108,6 @@ module Rack
124
108
  end
125
109
  }.join("&")
126
110
  end
127
- module_function :build_query
128
111
 
129
112
  def build_nested_query(value, prefix = nil)
130
113
  case value
@@ -143,11 +126,10 @@ module Rack
143
126
  "#{prefix}=#{escape(value)}"
144
127
  end
145
128
  end
146
- module_function :build_nested_query
147
129
 
148
130
  def q_values(q_value_header)
149
- q_value_header.to_s.split(',').map do |part|
150
- value, parameters = part.split(';', 2).map(&:strip)
131
+ q_value_header.to_s.split(/\s*,\s*/).map do |part|
132
+ value, parameters = part.split(/\s*;\s*/, 2)
151
133
  quality = 1.0
152
134
  if parameters && (md = /\Aq=([\d.]+)/.match(parameters))
153
135
  quality = md[1].to_f
@@ -155,8 +137,11 @@ module Rack
155
137
  [value, quality]
156
138
  end
157
139
  end
158
- module_function :q_values
159
140
 
141
+ # Return best accept value to use, based on the algorithm
142
+ # in RFC 2616 Section 14. If there are multiple best
143
+ # matches (same specificity and quality), the value returned
144
+ # is arbitrary.
160
145
  def best_q_match(q_value_header, available_mimes)
161
146
  values = q_values(q_value_header)
162
147
 
@@ -169,7 +154,6 @@ module Rack
169
154
  end.last
170
155
  matches && matches.first
171
156
  end
172
- module_function :best_q_match
173
157
 
174
158
  ESCAPE_HTML = {
175
159
  "&" => "&amp;",
@@ -186,22 +170,27 @@ module Rack
186
170
  def escape_html(string)
187
171
  string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
188
172
  end
189
- module_function :escape_html
190
173
 
191
174
  def select_best_encoding(available_encodings, accept_encoding)
192
175
  # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
193
176
 
194
- expanded_accept_encoding =
195
- accept_encoding.each_with_object([]) do |(m, q), list|
196
- if m == "*"
197
- (available_encodings - accept_encoding.map(&:first))
198
- .each { |m2| list << [m2, q] }
199
- else
200
- list << [m, q]
177
+ expanded_accept_encoding = []
178
+
179
+ accept_encoding.each do |m, q|
180
+ preference = available_encodings.index(m) || available_encodings.size
181
+
182
+ if m == "*"
183
+ (available_encodings - accept_encoding.map(&:first)).each do |m2|
184
+ expanded_accept_encoding << [m2, q, preference]
201
185
  end
186
+ else
187
+ expanded_accept_encoding << [m, q, preference]
202
188
  end
189
+ end
203
190
 
204
- encoding_candidates = expanded_accept_encoding.sort_by { |_, q| -q }.map!(&:first)
191
+ encoding_candidates = expanded_accept_encoding
192
+ .sort_by { |_, q, p| [-q, p] }
193
+ .map!(&:first)
205
194
 
206
195
  unless encoding_candidates.include?("identity")
207
196
  encoding_candidates.push("identity")
@@ -213,27 +202,19 @@ module Rack
213
202
 
214
203
  (encoding_candidates & available_encodings)[0]
215
204
  end
216
- module_function :select_best_encoding
217
205
 
218
206
  def parse_cookies(env)
219
207
  parse_cookies_header env[HTTP_COOKIE]
220
208
  end
221
- module_function :parse_cookies
222
209
 
223
210
  def parse_cookies_header(header)
224
- # According to RFC 2109:
225
- # If multiple cookies satisfy the criteria above, they are ordered in
226
- # the Cookie header such that those with more specific Path attributes
227
- # precede those with less specific. Ordering with respect to other
228
- # attributes (e.g., Domain) is unspecified.
229
- return {} unless header
230
- header.split(/[;,] */n).each_with_object({}) do |cookie, cookies|
231
- next if cookie.empty?
232
- key, value = cookie.split('=', 2)
233
- cookies[key] = (unescape(value) rescue value) unless cookies.key?(key)
234
- end
211
+ # According to RFC 6265:
212
+ # The syntax for cookie headers only supports semicolons
213
+ # User Agent -> Server ==
214
+ # Cookie: SID=31d4d96e407aad42; lang=en-US
215
+ cookies = parse_query(header, ';') { |s| unescape(s) rescue s }
216
+ cookies.each_with_object({}) { |(k, v), hash| hash[k] = Array === v ? v.first : v }
235
217
  end
236
- module_function :parse_cookies_header
237
218
 
238
219
  def add_cookie_to_header(header, key, value)
239
220
  case value
@@ -275,13 +256,11 @@ module Rack
275
256
  raise ArgumentError, "Unrecognized cookie header value. Expected String, Array, or nil, got #{header.inspect}"
276
257
  end
277
258
  end
278
- module_function :add_cookie_to_header
279
259
 
280
260
  def set_cookie_header!(header, key, value)
281
261
  header[SET_COOKIE] = add_cookie_to_header(header[SET_COOKIE], key, value)
282
262
  nil
283
263
  end
284
- module_function :set_cookie_header!
285
264
 
286
265
  def make_delete_cookie_header(header, key, value)
287
266
  case header
@@ -293,25 +272,30 @@ module Rack
293
272
  cookies = header
294
273
  end
295
274
 
296
- regexp = if value[:domain]
297
- /\A#{escape(key)}=.*domain=#{value[:domain]}/
298
- elsif value[:path]
299
- /\A#{escape(key)}=.*path=#{value[:path]}/
275
+ key = escape(key)
276
+ domain = value[:domain]
277
+ path = value[:path]
278
+ regexp = if domain
279
+ if path
280
+ /\A#{key}=.*(?:domain=#{domain}(?:;|$).*path=#{path}(?:;|$)|path=#{path}(?:;|$).*domain=#{domain}(?:;|$))/
281
+ else
282
+ /\A#{key}=.*domain=#{domain}(?:;|$)/
283
+ end
284
+ elsif path
285
+ /\A#{key}=.*path=#{path}(?:;|$)/
300
286
  else
301
- /\A#{escape(key)}=/
287
+ /\A#{key}=/
302
288
  end
303
289
 
304
290
  cookies.reject! { |cookie| regexp.match? cookie }
305
291
 
306
292
  cookies.join("\n")
307
293
  end
308
- module_function :make_delete_cookie_header
309
294
 
310
295
  def delete_cookie_header!(header, key, value = {})
311
296
  header[SET_COOKIE] = add_remove_cookie_to_header(header[SET_COOKIE], key, value)
312
297
  nil
313
298
  end
314
- module_function :delete_cookie_header!
315
299
 
316
300
  # Adds a cookie that will *remove* a cookie from the client. Hence the
317
301
  # strange method name.
@@ -324,12 +308,10 @@ module Rack
324
308
  expires: Time.at(0) }.merge(value))
325
309
 
326
310
  end
327
- module_function :add_remove_cookie_to_header
328
311
 
329
312
  def rfc2822(time)
330
313
  time.rfc2822
331
314
  end
332
- module_function :rfc2822
333
315
 
334
316
  # Modified version of stdlib time.rb Time#rfc2822 to use '%d-%b-%Y' instead
335
317
  # of '% %b %Y'.
@@ -345,7 +327,6 @@ module Rack
345
327
  mon = Time::RFC2822_MONTH_NAME[time.mon - 1]
346
328
  time.strftime("#{wday}, %d-#{mon}-%Y %H:%M:%S GMT")
347
329
  end
348
- module_function :rfc2109
349
330
 
350
331
  # Parses the "Range:" header, if present, into an array of Range objects.
351
332
  # Returns nil if the header is missing or syntactically invalid.
@@ -354,25 +335,23 @@ module Rack
354
335
  warn "`byte_ranges` is deprecated, please use `get_byte_ranges`" if $VERBOSE
355
336
  get_byte_ranges env['HTTP_RANGE'], size
356
337
  end
357
- module_function :byte_ranges
358
338
 
359
339
  def get_byte_ranges(http_range, size)
360
340
  # See <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35>
361
341
  return nil unless http_range && http_range =~ /bytes=([^;]+)/
362
342
  ranges = []
363
343
  $1.split(/,\s*/).each do |range_spec|
364
- return nil unless range_spec.include?('-')
365
- range = range_spec.split('-')
366
- r0, r1 = range[0], range[1]
367
- if r0.nil? || r0.empty?
368
- return nil if r1.nil?
344
+ return nil unless range_spec =~ /(\d*)-(\d*)/
345
+ r0, r1 = $1, $2
346
+ if r0.empty?
347
+ return nil if r1.empty?
369
348
  # suffix-byte-range-spec, represents trailing suffix of file
370
349
  r0 = size - r1.to_i
371
350
  r0 = 0 if r0 < 0
372
351
  r1 = size - 1
373
352
  else
374
353
  r0 = r0.to_i
375
- if r1.nil?
354
+ if r1.empty?
376
355
  r1 = size - 1
377
356
  else
378
357
  r1 = r1.to_i
@@ -384,7 +363,6 @@ module Rack
384
363
  end
385
364
  ranges
386
365
  end
387
- module_function :get_byte_ranges
388
366
 
389
367
  # Constant time string comparison.
390
368
  #
@@ -401,7 +379,6 @@ module Rack
401
379
  b.each_byte { |v| r |= v ^ l[i += 1] }
402
380
  r == 0
403
381
  end
404
- module_function :secure_compare
405
382
 
406
383
  # Context allows the use of a compatible middleware at different points
407
384
  # in a request handling stack. A compatible middleware must define
@@ -434,6 +411,14 @@ module Rack
434
411
  #
435
412
  # @api private
436
413
  class HeaderHash < Hash # :nodoc:
414
+ def self.[](headers)
415
+ if headers.is_a?(HeaderHash) && !headers.frozen?
416
+ return headers
417
+ else
418
+ return self.new(headers)
419
+ end
420
+ end
421
+
437
422
  def initialize(hash = {})
438
423
  super()
439
424
  @names = {}
@@ -446,6 +431,12 @@ module Rack
446
431
  @names = other.names.dup
447
432
  end
448
433
 
434
+ # on clear, we need to clear @names hash
435
+ def clear
436
+ super
437
+ @names.clear
438
+ end
439
+
449
440
  def each
450
441
  super do |k, v|
451
442
  yield(k, v.respond_to?(:to_ary) ? v.to_ary.join("\n") : v)
@@ -590,7 +581,6 @@ module Rack
590
581
  status.to_i
591
582
  end
592
583
  end
593
- module_function :status_code
594
584
 
595
585
  PATH_SEPS = Regexp.union(*[::File::SEPARATOR, ::File::ALT_SEPARATOR].compact)
596
586
 
@@ -604,18 +594,16 @@ module Rack
604
594
  part == '..' ? clean.pop : clean << part
605
595
  end
606
596
 
607
- clean.unshift '/' if parts.empty? || parts.first.empty?
608
-
609
- ::File.join clean
597
+ clean_path = clean.join(::File::SEPARATOR)
598
+ clean_path.prepend("/") if parts.empty? || parts.first.empty?
599
+ clean_path
610
600
  end
611
- module_function :clean_path_info
612
601
 
613
602
  NULL_BYTE = "\0"
614
603
 
615
604
  def valid_path?(path)
616
605
  path.valid_encoding? && !path.include?(NULL_BYTE)
617
606
  end
618
- module_function :valid_path?
619
607
 
620
608
  end
621
609
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2007-2019 Leah Neukirchen <http://leahneukirchen.org/infopage.html>
4
+ #
5
+ # Rack is freely distributable under the terms of an MIT-style license.
6
+ # See MIT-LICENSE or https://opensource.org/licenses/MIT.
7
+
8
+ # The Rack main module, serving as a namespace for all core Rack
9
+ # modules and classes.
10
+ #
11
+ # All modules meant for use in your application are <tt>autoload</tt>ed here,
12
+ # so it should be enough just to <tt>require 'rack'</tt> in your code.
13
+
14
+ module Rack
15
+ # The Rack protocol version number implemented.
16
+ VERSION = [1, 3]
17
+
18
+ # Return the Rack protocol version as a dotted string.
19
+ def self.version
20
+ VERSION.join(".")
21
+ end
22
+
23
+ RELEASE = "2.2.0"
24
+
25
+ # Return the Rack release as a dotted string.
26
+ def self.release
27
+ RELEASE
28
+ end
29
+ end
data/lib/rack.rb CHANGED
@@ -11,23 +11,11 @@
11
11
  # All modules meant for use in your application are <tt>autoload</tt>ed here,
12
12
  # so it should be enough just to <tt>require 'rack'</tt> in your code.
13
13
 
14
- module Rack
15
- # The Rack protocol version number implemented.
16
- VERSION = [1, 3]
17
-
18
- # Return the Rack protocol version as a dotted string.
19
- def self.version
20
- VERSION.join(".")
21
- end
22
-
23
- RELEASE = "2.1.4.4"
24
-
25
- # Return the Rack release as a dotted string.
26
- def self.release
27
- RELEASE
28
- end
14
+ require_relative 'rack/version'
29
15
 
16
+ module Rack
30
17
  HTTP_HOST = 'HTTP_HOST'
18
+ HTTP_PORT = 'HTTP_PORT'
31
19
  HTTP_VERSION = 'HTTP_VERSION'
32
20
  HTTPS = 'HTTPS'
33
21
  PATH_INFO = 'PATH_INFO'
@@ -37,9 +25,9 @@ module Rack
37
25
  QUERY_STRING = 'QUERY_STRING'
38
26
  SERVER_PROTOCOL = 'SERVER_PROTOCOL'
39
27
  SERVER_NAME = 'SERVER_NAME'
40
- SERVER_ADDR = 'SERVER_ADDR'
41
28
  SERVER_PORT = 'SERVER_PORT'
42
29
  CACHE_CONTROL = 'Cache-Control'
30
+ EXPIRES = 'Expires'
43
31
  CONTENT_LENGTH = 'Content-Length'
44
32
  CONTENT_TYPE = 'Content-Type'
45
33
  SET_COOKIE = 'Set-Cookie'
@@ -98,6 +86,7 @@ module Rack
98
86
  autoload :ContentLength, "rack/content_length"
99
87
  autoload :ContentType, "rack/content_type"
100
88
  autoload :ETag, "rack/etag"
89
+ autoload :Events, "rack/events"
101
90
  autoload :File, "rack/file"
102
91
  autoload :Files, "rack/files"
103
92
  autoload :Deflater, "rack/deflater"
@@ -108,11 +97,13 @@ module Rack
108
97
  autoload :Lint, "rack/lint"
109
98
  autoload :Lock, "rack/lock"
110
99
  autoload :Logger, "rack/logger"
100
+ autoload :MediaType, "rack/media_type"
111
101
  autoload :MethodOverride, "rack/method_override"
112
102
  autoload :Mime, "rack/mime"
113
103
  autoload :NullLogger, "rack/null_logger"
114
104
  autoload :Recursive, "rack/recursive"
115
105
  autoload :Reloader, "rack/reloader"
106
+ autoload :RewindableInput, "rack/rewindable_input"
116
107
  autoload :Runtime, "rack/runtime"
117
108
  autoload :Sendfile, "rack/sendfile"
118
109
  autoload :Server, "rack/server"
data/rack.gemspec CHANGED
@@ -1,39 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'lib/rack/version'
4
+
3
5
  Gem::Specification.new do |s|
4
6
  s.name = "rack"
5
- s.version = File.read('lib/rack.rb')[/RELEASE += +([\"\'])([\d][\w\.]+)\1/, 2]
6
- s.platform = Gem::Platform::RUBY
7
- s.summary = "a modular Ruby webserver interface"
8
- s.license = "MIT"
9
-
10
- s.description = <<-EOF
11
- Rack provides a minimal, modular and adaptable interface for developing
12
- web applications in Ruby. By wrapping HTTP requests and responses in
13
- the simplest way possible, it unifies and distills the API for web
14
- servers, web frameworks, and software in between (the so-called
15
- middleware) into a single method call.
16
-
17
- Also see https://rack.github.io/.
18
- EOF
19
-
20
- s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*}'] +
21
- %w(MIT-LICENSE rack.gemspec Rakefile README.rdoc SPEC)
22
- s.bindir = 'bin'
7
+ s.version = Rack::RELEASE
8
+ s.platform = Gem::Platform::RUBY
9
+ s.summary = "A modular Ruby webserver interface."
10
+ s.license = "MIT"
11
+
12
+ s.description = <<~EOF
13
+ Rack provides a minimal, modular and adaptable interface for developing
14
+ web applications in Ruby. By wrapping HTTP requests and responses in
15
+ the simplest way possible, it unifies and distills the API for web
16
+ servers, web frameworks, and software in between (the so-called
17
+ middleware) into a single method call.
18
+ EOF
19
+
20
+ s.files = Dir['{bin/*,contrib/*,example/*,lib/**/*}'] +
21
+ %w(MIT-LICENSE rack.gemspec Rakefile README.rdoc SPEC.rdoc)
22
+
23
+ s.bindir = 'bin'
23
24
  s.executables << 'rackup'
24
25
  s.require_path = 'lib'
25
- s.extra_rdoc_files = ['README.rdoc', 'CHANGELOG.md']
26
-
27
- s.author = 'Leah Neukirchen'
28
- s.email = 'leah@vuxu.org'
29
- s.homepage = 'https://rack.github.io/'
30
- s.required_ruby_version = '>= 2.2.2'
31
- s.metadata = {
32
- "bug_tracker_uri" => "https://github.com/rack/rack/issues",
33
- "changelog_uri" => "https://github.com/rack/rack/blob/master/CHANGELOG.md",
26
+ s.extra_rdoc_files = ['README.rdoc', 'CHANGELOG.md', 'CONTRIBUTING.md']
27
+
28
+ s.author = 'Leah Neukirchen'
29
+ s.email = 'leah@vuxu.org'
30
+
31
+ s.homepage = 'https://github.com/rack/rack'
32
+
33
+ s.required_ruby_version = '>= 2.3.0'
34
+
35
+ s.metadata = {
36
+ "bug_tracker_uri" => "https://github.com/rack/rack/issues",
37
+ "changelog_uri" => "https://github.com/rack/rack/blob/master/CHANGELOG.md",
34
38
  "documentation_uri" => "https://rubydoc.info/github/rack/rack",
35
- "homepage_uri" => "https://rack.github.io",
36
- "mailing_list_uri" => "https://groups.google.com/forum/#!forum/rack-devel",
37
39
  "source_code_uri" => "https://github.com/rack/rack"
38
40
  }
39
41
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.4.4
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leah Neukirchen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-21 00:00:00.000000000 Z
11
+ date: 2020-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -68,12 +68,10 @@ dependencies:
68
68
  version: '0'
69
69
  description: |
70
70
  Rack provides a minimal, modular and adaptable interface for developing
71
- web applications in Ruby. By wrapping HTTP requests and responses in
71
+ web applications in Ruby. By wrapping HTTP requests and responses in
72
72
  the simplest way possible, it unifies and distills the API for web
73
73
  servers, web frameworks, and software in between (the so-called
74
74
  middleware) into a single method call.
75
-
76
- Also see https://rack.github.io/.
77
75
  email: leah@vuxu.org
78
76
  executables:
79
77
  - rackup
@@ -81,12 +79,14 @@ extensions: []
81
79
  extra_rdoc_files:
82
80
  - README.rdoc
83
81
  - CHANGELOG.md
82
+ - CONTRIBUTING.md
84
83
  files:
85
84
  - CHANGELOG.md
85
+ - CONTRIBUTING.md
86
86
  - MIT-LICENSE
87
87
  - README.rdoc
88
88
  - Rakefile
89
- - SPEC
89
+ - SPEC.rdoc
90
90
  - bin/rackup
91
91
  - contrib/rack.png
92
92
  - contrib/rack.svg
@@ -159,18 +159,17 @@ files:
159
159
  - lib/rack/tempfile_reaper.rb
160
160
  - lib/rack/urlmap.rb
161
161
  - lib/rack/utils.rb
162
+ - lib/rack/version.rb
162
163
  - rack.gemspec
163
- homepage: https://rack.github.io/
164
+ homepage: https://github.com/rack/rack
164
165
  licenses:
165
166
  - MIT
166
167
  metadata:
167
168
  bug_tracker_uri: https://github.com/rack/rack/issues
168
169
  changelog_uri: https://github.com/rack/rack/blob/master/CHANGELOG.md
169
170
  documentation_uri: https://rubydoc.info/github/rack/rack
170
- homepage_uri: https://rack.github.io
171
- mailing_list_uri: https://groups.google.com/forum/#!forum/rack-devel
172
171
  source_code_uri: https://github.com/rack/rack
173
- post_install_message:
172
+ post_install_message:
174
173
  rdoc_options: []
175
174
  require_paths:
176
175
  - lib
@@ -178,15 +177,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
178
177
  requirements:
179
178
  - - ">="
180
179
  - !ruby/object:Gem::Version
181
- version: 2.2.2
180
+ version: 2.3.0
182
181
  required_rubygems_version: !ruby/object:Gem::Requirement
183
182
  requirements:
184
183
  - - ">="
185
184
  - !ruby/object:Gem::Version
186
185
  version: '0'
187
186
  requirements: []
188
- rubygems_version: 3.4.10
189
- signing_key:
187
+ rubygems_version: 3.1.2
188
+ signing_key:
190
189
  specification_version: 4
191
- summary: a modular Ruby webserver interface
190
+ summary: A modular Ruby webserver interface.
192
191
  test_files: []