rack-contrib 2.3.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf14e9cb70d9701bc1f3fe5ce036a0667f4ba6c9411e0e6ded73ef958228ec45
4
- data.tar.gz: d0c2abe31908dd0d49dec3635cca17c720c94d098a04e9485adf917c469e0ee5
3
+ metadata.gz: 1b83b23d3e67c0a24d65f6da2406e8430b003100bae5b5e8f3b20486384804e0
4
+ data.tar.gz: 4e2b5a6b94dbd7be2b10a6dae026509166d236e0b0e842f0a127b59d28298ae9
5
5
  SHA512:
6
- metadata.gz: f352f5eac5008e79d645460cd9b17dcc7231fe55edb63a0540c6c0991c06ba5f989cd70c23453e854a8189bcd02ad1be96366bb4d24efdaccefc5fe823a9eed5
7
- data.tar.gz: 379d6d0190a63d1df9c615e2fdd53bfebcac0cf506407e1e8a11c734ffc955f066a2aa56e79db21458b62efbb6603e1749f1bdddaed1c35fb84a69cd494dba8f
6
+ metadata.gz: a12773ffdd9646740002b8124c2bd02bdc92d738ced7c4bb270e6003661a259d4dc8e34925bd909805bd1e40a0d381b9efa59c3d2d02d1fe5f9dcd57af8809c9
7
+ data.tar.gz: c9955bcfb8787a930d9590cc984ab16a25211e2f52b9fe76b7d357088bbc68503e1c2fc362c46ba0c8febb08aa73eb67ed04bd03ddbdea39bd489e336211d385
data/README.md CHANGED
@@ -76,7 +76,7 @@ To contribute to the project, begin by cloning the repo and installing the neces
76
76
 
77
77
  gem install json rack ruby-prof test-spec test-unit
78
78
 
79
- To run the entire test suite, run
79
+ To run the entire test suite, run
80
80
 
81
81
  rake test
82
82
 
@@ -84,7 +84,7 @@ To run a specific component's tests run
84
84
 
85
85
  specrb -Ilib:test -w test/spec_rack_thecomponent.rb
86
86
 
87
- This works on ruby 1.8.7 but has problems under ruby 1.9.x.
87
+ This works on ruby 1.8.7 but has problems under ruby 1.9.x.
88
88
 
89
89
  TODO: instructions for 1.9.x and include bundler
90
90
 
@@ -98,10 +98,16 @@ The criteria for middleware being included in this project are roughly as follow
98
98
  These criteria were introduced several years after the start of the project, so some of the included middleware may not meet all of them. In particular, several middleware have external dependencies. It is possible that in some future release of rack-contrib, middleware with external depencies will be removed from the project.
99
99
 
100
100
  When submitting code keep the above criteria in mind and also see the code
101
- guidelines in CONTRIBUTING.md.
101
+ guidelines in CONTRIBUTING.md.
102
102
 
103
103
  ### Links
104
104
 
105
105
  * rack-contrib on GitHub:: <https://github.com/rack/rack-contrib>
106
106
  * Rack:: <https://rack.github.io/>
107
107
  * Rack On GitHub:: <https://github.com/rack/rack>
108
+
109
+
110
+ ### Security Reporting
111
+
112
+ To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
113
+ Tidelift will coordinate the fix and disclosure.
@@ -40,7 +40,7 @@ module Rack
40
40
  raise ArgumentError, "paths need to start with /"
41
41
  end
42
42
  location = location.chomp('/')
43
- match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n')
43
+ match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", Regexp::NOENCODING)
44
44
 
45
45
  ipmasks.collect! do |ipmask|
46
46
  ipmask.is_a?(IPAddr) ? ipmask : IPAddr.new(ipmask)
@@ -72,7 +72,7 @@ module Rack
72
72
  end
73
73
 
74
74
  def forbidden!
75
- [403, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []]
75
+ [403, { 'content-type' => 'text/html', 'content-length' => '0' }, []]
76
76
  end
77
77
 
78
78
  def ip_authorized?(request, ipmasks)
@@ -10,10 +10,10 @@ module Rack
10
10
  end
11
11
 
12
12
  def call(env)
13
- if File.exists?(@file)
13
+ if File.exist?(@file)
14
14
  content = File.read(@file)
15
15
  length = content.bytesize.to_s
16
- [503, {'Content-Type' => 'text/html', 'Content-Length' => length}, [content]]
16
+ [503, {'content-type' => 'text/html', 'content-length' => length}, [content]]
17
17
  else
18
18
  @app.call(env)
19
19
  end
@@ -9,7 +9,7 @@ module Rack
9
9
 
10
10
  def call(env)
11
11
  if env["PATH_INFO"] == "/favicon.ico"
12
- [404, {"Content-Type" => "text/html", "Content-Length" => "0"}, []]
12
+ [404, {"content-type" => "text/html", "content-length" => "0"}, []]
13
13
  else
14
14
  @app.call(env)
15
15
  end
@@ -7,13 +7,16 @@ module Rack
7
7
  LOCALHOST_OR_IP_REGEXP = /^([\d.]+|localhost)$/
8
8
  PORT = /:\d+$/
9
9
 
10
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
11
+ private_constant :HEADERS_KLASS
12
+
10
13
  def initialize(app)
11
14
  @app = app
12
15
  end
13
16
 
14
17
  def call(env)
15
18
  status, headers, body = @app.call(env)
16
- headers = Utils::HeaderHash.new(headers)
19
+ headers = HEADERS_KLASS.new.merge(headers)
17
20
 
18
21
  host = env['HTTP_HOST'].sub PORT, ''
19
22
  share_cookie(headers, host)
@@ -6,6 +6,8 @@ module Rack
6
6
 
7
7
  # A Rack middleware for providing CSSHTTPRequest responses.
8
8
  class CSSHTTPRequest
9
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
10
+ private_constant :HEADERS_KLASS
9
11
 
10
12
  def initialize(app)
11
13
  @app = app
@@ -15,7 +17,7 @@ module Rack
15
17
  # the CSSHTTPRequest encoder
16
18
  def call(env)
17
19
  status, headers, response = @app.call(env)
18
- headers = Utils::HeaderHash.new(headers)
20
+ headers = HEADERS_KLASS.new.merge(headers)
19
21
 
20
22
  if chr_request?(env)
21
23
  encoded_response = encode(response)
@@ -65,7 +65,7 @@ module Rack
65
65
  end
66
66
 
67
67
  def deflect!
68
- [403, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []]
68
+ [403, { 'content-type' => 'text/html', 'content-length' => '0' }, []]
69
69
  end
70
70
 
71
71
  def deflect? env
@@ -18,7 +18,7 @@ module Rack
18
18
  Rack::Utils.unescape(full_path).valid_encoding?
19
19
  @app.call env
20
20
  else
21
- [400, {'Content-Type'=>'text/plain'}, ['Bad Request']]
21
+ [400, {'content-type'=>'text/plain'}, ['Bad Request']]
22
22
  end
23
23
  end
24
24
  end
@@ -5,8 +5,8 @@ module Rack
5
5
  Expect = "HTTP_EXPECT".freeze
6
6
  ContinueExpectation = "100-continue".freeze
7
7
 
8
- ExpectationFailed = [417, {"Content-Type" => "text/html"}, []].freeze
9
- NotFound = [404, {"Content-Type" => "text/html"}, []].freeze
8
+ ExpectationFailed = [417, {"content-type" => "text/html"}, []]
9
+ NotFound = [404, {"content-type" => "text/html"}, []]
10
10
 
11
11
  attr_reader :apps
12
12
 
@@ -30,7 +30,7 @@ module Rack
30
30
 
31
31
  def call(env)
32
32
  if env['PATH_INFO'] == '/host-meta'
33
- [200, {'Content-Type' => 'application/host-meta'}, [@response]]
33
+ [200, {'content-type' => 'application/host-meta'}, [@response]]
34
34
  else
35
35
  @app.call(env)
36
36
  end
@@ -14,10 +14,10 @@ module Rack
14
14
  # === Parse POST and GET requests only
15
15
  # use Rack::JSONBodyParser, verbs: ['POST', 'GET']
16
16
  #
17
- # === Parse POST|PATCH|PUT requests whose Content-Type matches 'json'
17
+ # === Parse POST|PATCH|PUT requests whose content-type matches 'json'
18
18
  # use Rack::JSONBodyParser, media: /json/
19
19
  #
20
- # === Parse POST requests whose Content-Type is 'application/json' or 'application/vnd+json'
20
+ # === Parse POST requests whose content-type is 'application/json' or 'application/vnd+json'
21
21
  # use Rack::JSONBodyParser, verbs: ['POST'], media: ['application/json', 'application/vnd.api+json']
22
22
  #
23
23
  class JSONBodyParser
@@ -61,9 +61,9 @@ module Rack
61
61
 
62
62
  update_form_hash_with_json_body(env)
63
63
  end
64
- rescue JSON::ParserError
64
+ rescue ParserError
65
65
  body = { error: 'Failed to parse body as JSON' }.to_json
66
- header = { 'Content-Type' => 'application/json' }
66
+ header = { 'content-type' => 'application/json' }
67
67
  return Rack::Response.new(body, 400, header).finish
68
68
  end
69
69
  @app.call(env)
@@ -71,13 +71,22 @@ module Rack
71
71
 
72
72
  private
73
73
 
74
+ class ParserError < StandardError; end
75
+
74
76
  def update_form_hash_with_json_body(env)
75
77
  body = env[Rack::RACK_INPUT]
76
78
  return unless (body_content = body.read) && !body_content.empty?
77
79
 
78
- body.rewind # somebody might try to read this stream
80
+ body.rewind if body.respond_to?(:rewind) # somebody might try to read this stream
81
+
82
+ begin
83
+ parsed_body = @parser.call(body_content)
84
+ rescue StandardError
85
+ raise ParserError
86
+ end
87
+
79
88
  env.update(
80
- Rack::RACK_REQUEST_FORM_HASH => @parser.call(body_content),
89
+ Rack::RACK_REQUEST_FORM_HASH => parsed_body,
81
90
  Rack::RACK_REQUEST_FORM_INPUT => body
82
91
  )
83
92
  end
@@ -23,6 +23,9 @@ module Rack
23
23
  # "\342\200\251" # => "\u2029"
24
24
  U2028, U2029 = ("\u2028" == 'u2028') ? ["\342\200\250", "\342\200\251"] : ["\u2028", "\u2029"]
25
25
 
26
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
27
+ private_constant :HEADERS_KLASS
28
+
26
29
  def initialize(app)
27
30
  @app = app
28
31
  end
@@ -42,7 +45,7 @@ module Rack
42
45
  return status, headers, response
43
46
  end
44
47
 
45
- headers = HeaderHash.new(headers)
48
+ headers = HEADERS_KLASS.new.merge(headers)
46
49
 
47
50
  if is_json?(headers) && has_callback?(request)
48
51
  callback = request.params['callback']
@@ -108,7 +111,7 @@ module Rack
108
111
  end
109
112
 
110
113
  def bad_request(body = "Bad Request")
111
- [ 400, { 'Content-Type' => 'text/plain', 'Content-Length' => body.bytesize.to_s }, [body] ]
114
+ [ 400, { 'content-type' => 'text/plain', 'content-length' => body.bytesize.to_s }, [body] ]
112
115
  end
113
116
 
114
117
  end
@@ -74,14 +74,14 @@ module Rack
74
74
 
75
75
  def call env
76
76
  if reading? env and fresh? env
77
- return [304, {'Last-Modified' => env['HTTP_IF_MODIFIED_SINCE']}, []]
77
+ return [304, {'last-modified' => env['HTTP_IF_MODIFIED_SINCE']}, []]
78
78
  end
79
79
 
80
80
  status, headers, body = @app.call env
81
- headers = Utils::HeaderHash.new(headers)
81
+ headers = Rack.release < "3" ? Utils::HeaderHash.new(headers) : headers
82
82
 
83
83
  update_cache unless (reading?(env) or skipping?(headers))
84
- headers['Last-Modified'] = cached_value if stampable? headers
84
+ headers['last-modified'] = cached_value if stampable? headers
85
85
  [status, headers, body]
86
86
  end
87
87
 
@@ -96,11 +96,11 @@ module Rack
96
96
  end
97
97
 
98
98
  def skipping? headers
99
- headers['Rack-Lazy-Conditional-Get'] == 'skip'
99
+ headers['rack-lazy-conditional-get'] == 'skip'
100
100
  end
101
101
 
102
102
  def stampable? headers
103
- !headers.has_key?('Last-Modified') and headers['Rack-Lazy-Conditional-Get'] == 'yes'
103
+ !headers.has_key?('last-modified') and headers['rack-lazy-conditional-get'] == 'yes'
104
104
  end
105
105
 
106
106
  def update_cache
@@ -4,6 +4,9 @@ require 'i18n'
4
4
 
5
5
  module Rack
6
6
  class Locale
7
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
8
+ private_constant :HEADERS_KLASS
9
+
7
10
  def initialize(app)
8
11
  @app = app
9
12
  end
@@ -16,7 +19,7 @@ module Rack
16
19
 
17
20
  env['rack.locale'] = I18n.locale = locale.to_s
18
21
  status, headers, body = @app.call(env)
19
- headers = Utils::HeaderHash.new(headers)
22
+ headers = HEADERS_KLASS.new.merge(headers)
20
23
 
21
24
  unless headers['Content-Language']
22
25
  headers['Content-Language'] = locale.to_s
@@ -69,9 +72,12 @@ module Rack
69
72
 
70
73
  if I18n.enforce_available_locales
71
74
  locale = locales.reverse.find { |locale| I18n.available_locales.any? { |al| match?(al, locale) } }
72
- if locale
73
- I18n.available_locales.find { |al| match?(al, locale) }
75
+ matched_locale = I18n.available_locales.find { |al| match?(al, locale) } if locale
76
+ if !locale && !matched_locale
77
+ matched_locale = locales.reverse.find { |locale| I18n.available_locales.any? { |al| variant_match?(al, locale) } }
78
+ matched_locale = matched_locale[0,2] if matched_locale
74
79
  end
80
+ matched_locale
75
81
  else
76
82
  locales.last
77
83
  end
@@ -80,5 +86,9 @@ module Rack
80
86
  def match?(s1, s2)
81
87
  s1.to_s.casecmp(s2.to_s) == 0
82
88
  end
89
+
90
+ def variant_match?(s1, s2)
91
+ s1.to_s.casecmp(s2[0,2].to_s) == 0
92
+ end
83
93
  end
84
94
  end
@@ -106,7 +106,7 @@ module Rack
106
106
 
107
107
  def extract_body(env)
108
108
  if io = env['rack.input']
109
- io.rewind
109
+ io.rewind if io.respond_to?(:rewind)
110
110
  io.read
111
111
  end
112
112
  end
@@ -27,7 +27,7 @@ module Rack
27
27
  end
28
28
 
29
29
  def call(env)
30
- [404, {'Content-Type' => @content_type, 'Content-Length' => @length}, [@content]]
30
+ [404, {'content-type' => @content_type, 'content-length' => @length}, [@content]]
31
31
  end
32
32
  end
33
33
  end
@@ -75,7 +75,7 @@ module Rack
75
75
 
76
76
  def call(env)
77
77
  if Rack::Request.new(env).media_type == APPLICATION_JSON && (body = env[POST_BODY].read).length != 0
78
- env[POST_BODY].rewind # somebody might try to read this stream
78
+ env[POST_BODY].rewind if env[POST_BODY].respond_to?(:rewind) # somebody might try to read this stream
79
79
  env.update(FORM_HASH => @block.call(body), FORM_INPUT => env[POST_BODY])
80
80
  end
81
81
  @app.call(env)
@@ -84,7 +84,7 @@ module Rack
84
84
  end
85
85
 
86
86
  def bad_request(body = 'Bad Request')
87
- [ 400, { 'Content-Type' => 'text/plain', 'Content-Length' => body.bytesize.to_s }, [body] ]
87
+ [ 400, { 'content-type' => 'text/plain', 'content-length' => body.bytesize.to_s }, [body] ]
88
88
  end
89
89
  end
90
90
  end
@@ -8,7 +8,7 @@ module Rack
8
8
  end
9
9
 
10
10
  def call(env)
11
- # See http://rack.rubyforge.org/doc/SPEC.html for details
11
+ # See https://github.com/rack/rack/blob/main/SPEC.rdoc for details
12
12
  puts "**********\n Environment\n **************"
13
13
  puts env.inspect
14
14
 
@@ -32,10 +32,14 @@ module Rack
32
32
  # option defaulting to :call_stack.
33
33
  def initialize(app, options = {})
34
34
  @app = app
35
+ @profile = nil
35
36
  @printer = parse_printer(options[:printer] || DEFAULT_PRINTER)
36
37
  @times = (options[:times] || 1).to_i
38
+ @maximum_runs = options.fetch(:maximum_runs, 10)
37
39
  end
38
40
 
41
+ attr :maximum_runs
42
+
39
43
  def call(env)
40
44
  if mode = profiling?(env)
41
45
  profile(env, mode)
@@ -46,28 +50,46 @@ module Rack
46
50
 
47
51
  private
48
52
  def profiling?(env)
49
- unless ::RubyProf.running?
50
- request = Rack::Request.new(env.clone)
51
- if mode = request.params.delete('profile')
52
- if ::RubyProf.const_defined?(mode.upcase)
53
- mode
54
- else
55
- env['rack.errors'].write "Invalid RubyProf measure_mode: " +
56
- "#{mode}. Use one of #{MODES.to_a.join(', ')}"
57
- false
58
- end
53
+ return if @profile && @profile.running?
54
+
55
+ request = Rack::Request.new(env.clone)
56
+ if mode = request.params.delete('profile')
57
+ if ::RubyProf.const_defined?(mode.upcase)
58
+ mode
59
+ else
60
+ env['rack.errors'].write "Invalid RubyProf measure_mode: " +
61
+ "#{mode}. Use one of #{MODES.to_a.join(', ')}"
62
+ false
63
+ end
64
+ end
65
+ end
66
+
67
+ # How many times to run the request within the profiler.
68
+ # If the profiler_runs query parameter is set, use that.
69
+ # Otherwise, use the :times option passed to `#initialize`.
70
+ # If the profiler_runs query parameter is greater than the
71
+ # :maximum option passed to `#initialize`, use the :maximum
72
+ # option.
73
+ def runs(request)
74
+ if profiler_runs = request.params['profiler_runs']
75
+ profiler_runs = profiler_runs.to_i
76
+ if profiler_runs > @maximum_runs
77
+ return @maximum_runs
78
+ else
79
+ return profiler_runs
59
80
  end
81
+ else
82
+ return @times
60
83
  end
61
84
  end
62
85
 
63
86
  def profile(env, mode)
64
- ::RubyProf.measure_mode = ::RubyProf.const_get(mode.upcase)
87
+ @profile = ::RubyProf::Profile.new(measure_mode: ::RubyProf.const_get(mode.upcase))
65
88
 
66
89
  GC.enable_stats if GC.respond_to?(:enable_stats)
67
90
  request = Rack::Request.new(env.clone)
68
- runs = (request.params['profiler_runs'] || @times).to_i
69
- result = ::RubyProf.profile do
70
- runs.times { @app.call(env) }
91
+ result = @profile.profile do
92
+ runs(request).times { @app.call(env) }
71
93
  end
72
94
  GC.disable_stats if GC.respond_to?(:disable_stats)
73
95
 
@@ -82,10 +104,10 @@ module Rack
82
104
  end
83
105
 
84
106
  def headers(printer, env, mode)
85
- headers = { 'Content-Type' => CONTENT_TYPES[printer.name] }
107
+ headers = { 'content-type' => CONTENT_TYPES[printer.name] }
86
108
  if printer == ::RubyProf::CallTreePrinter
87
109
  filename = ::File.basename(env['PATH_INFO'])
88
- headers['Content-Disposition'] =
110
+ headers['content-disposition'] =
89
111
  %(attachment; filename="#{filename}.#{mode}.tree")
90
112
  end
91
113
  headers
@@ -33,7 +33,8 @@ class Rack::RelativeRedirect
33
33
  # does not start with a slash, make location relative to the path requested.
34
34
  def call(env)
35
35
  status, headers, body = @app.call(env)
36
- headers = Rack::Utils::HeaderHash.new(headers)
36
+ headers_klass = Rack.release < "3" ? Rack::Utils::HeaderHash : Rack::Headers
37
+ headers = headers_klass.new.merge(headers)
37
38
 
38
39
  if [301,302,303, 307,308].include?(status) and loc = headers['Location'] and !%r{\Ahttps?://}o.match(loc)
39
40
  absolute = @absolute_proc.call(env, [status, headers, body])
@@ -53,7 +53,8 @@ class Rack::ResponseCache
53
53
  # subdirectory of cache. Otherwise, cache the body of the response as the value with the path as the key.
54
54
  def call(env)
55
55
  status, headers, body = @app.call(env)
56
- headers = Rack::Utils::HeaderHash.new(headers)
56
+ headers_klass = Rack.release < "3" ? Rack::Utils::HeaderHash : Rack::Headers
57
+ headers = headers_klass.new.merge(headers)
57
58
 
58
59
  if env['REQUEST_METHOD'] == 'GET' and env['QUERY_STRING'] == '' and status == 200 and path = @path_proc.call(env, [status, headers, body])
59
60
  if @cache.is_a?(String)
@@ -2,7 +2,8 @@
2
2
 
3
3
  module Rack
4
4
  # Allows you to tap into the response headers. Yields a Rack::Utils::HeaderHash
5
- # of current response headers to the block. Example:
5
+ # (Rack 2) or a Rack::Headers (Rack 3) of current response headers to the block.
6
+ # Example:
6
7
  #
7
8
  # use Rack::ResponseHeaders do |headers|
8
9
  # headers['X-Foo'] = 'bar'
@@ -10,6 +11,9 @@ module Rack
10
11
  # end
11
12
  #
12
13
  class ResponseHeaders
14
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
15
+ private_constant :HEADERS_KLASS
16
+
13
17
  def initialize(app, &block)
14
18
  @app = app
15
19
  @block = block
@@ -17,7 +21,7 @@ module Rack
17
21
 
18
22
  def call(env)
19
23
  response = @app.call(env)
20
- headers = Utils::HeaderHash.new(response[1])
24
+ headers = HEADERS_KLASS.new.merge(response[1])
21
25
  @block.call(headers)
22
26
  response[1] = headers
23
27
  response
@@ -52,6 +52,8 @@ module Rack
52
52
 
53
53
 
54
54
  class StaticCache
55
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
56
+ private_constant :HEADERS_KLASS
55
57
 
56
58
  def initialize(app, options={})
57
59
  @app = app
@@ -67,7 +69,7 @@ module Rack
67
69
  end
68
70
  end
69
71
  root = options[:root] || Dir.pwd
70
- @file_server = Rack::File.new(root)
72
+ @file_server = Rack::Files.new(root)
71
73
  @cache_duration = options[:duration] || 1
72
74
  @versioning_enabled = options.fetch(:versioning, true)
73
75
  if @versioning_enabled
@@ -87,7 +89,7 @@ module Rack
87
89
  end
88
90
 
89
91
  status, headers, body = @file_server.call(env)
90
- headers = Utils::HeaderHash.new(headers)
92
+ headers = HEADERS_KLASS.new.merge(headers)
91
93
 
92
94
  if @no_cache[url].nil?
93
95
  headers['Cache-Control'] ="max-age=#{@duration_in_seconds}, public"
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ module Contrib
3
+ VERSION = '2.5.0'
4
+ end
5
+ end
metadata CHANGED
@@ -1,249 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-contrib
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rack-devel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-24 00:00:00.000000000 Z
11
+ date: 2024-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.0'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '1.0'
34
17
  - - "<"
35
18
  - !ruby/object:Gem::Version
36
- version: '3'
37
- type: :development
19
+ version: '4'
20
+ type: :runtime
38
21
  prerelease: false
39
22
  version_requirements: !ruby/object:Gem::Requirement
40
23
  requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: '1.0'
44
24
  - - "<"
45
25
  - !ruby/object:Gem::Version
46
- version: '3'
47
- - !ruby/object:Gem::Dependency
48
- name: git-version-bump
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: '0.15'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: '0.15'
61
- - !ruby/object:Gem::Dependency
62
- name: github-release
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '0.1'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '0.1'
75
- - !ruby/object:Gem::Dependency
76
- name: i18n
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '0.6'
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: 0.6.8
85
- type: :development
86
- prerelease: false
87
- version_requirements: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - "~>"
90
- - !ruby/object:Gem::Version
91
- version: '0.6'
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: 0.6.8
95
- - !ruby/object:Gem::Dependency
96
- name: json
97
- requirement: !ruby/object:Gem::Requirement
98
- requirements:
99
- - - "~>"
100
- - !ruby/object:Gem::Version
101
- version: '2.0'
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- requirements:
106
- - - "~>"
107
- - !ruby/object:Gem::Version
108
- version: '2.0'
109
- - !ruby/object:Gem::Dependency
110
- name: mime-types
111
- requirement: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - "~>"
114
- - !ruby/object:Gem::Version
115
- version: '3.0'
116
- type: :development
117
- prerelease: false
118
- version_requirements: !ruby/object:Gem::Requirement
119
- requirements:
120
- - - "~>"
121
- - !ruby/object:Gem::Version
122
- version: '3.0'
123
- - !ruby/object:Gem::Dependency
124
- name: minitest
125
- requirement: !ruby/object:Gem::Requirement
126
- requirements:
127
- - - "~>"
128
- - !ruby/object:Gem::Version
129
- version: '5.6'
130
- type: :development
131
- prerelease: false
132
- version_requirements: !ruby/object:Gem::Requirement
133
- requirements:
134
- - - "~>"
135
- - !ruby/object:Gem::Version
136
- version: '5.6'
137
- - !ruby/object:Gem::Dependency
138
- name: minitest-hooks
139
- requirement: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - "~>"
142
- - !ruby/object:Gem::Version
143
- version: '1.0'
144
- type: :development
145
- prerelease: false
146
- version_requirements: !ruby/object:Gem::Requirement
147
- requirements:
148
- - - "~>"
149
- - !ruby/object:Gem::Version
150
- version: '1.0'
151
- - !ruby/object:Gem::Dependency
152
- name: mail
153
- requirement: !ruby/object:Gem::Requirement
154
- requirements:
155
- - - "~>"
156
- - !ruby/object:Gem::Version
157
- version: '2.3'
158
- - - ">="
159
- - !ruby/object:Gem::Version
160
- version: 2.6.4
161
- type: :development
162
- prerelease: false
163
- version_requirements: !ruby/object:Gem::Requirement
164
- requirements:
165
- - - "~>"
166
- - !ruby/object:Gem::Version
167
- version: '2.3'
168
- - - ">="
169
- - !ruby/object:Gem::Version
170
- version: 2.6.4
171
- - !ruby/object:Gem::Dependency
172
- name: nbio-csshttprequest
173
- requirement: !ruby/object:Gem::Requirement
174
- requirements:
175
- - - "~>"
176
- - !ruby/object:Gem::Version
177
- version: '1.0'
178
- type: :development
179
- prerelease: false
180
- version_requirements: !ruby/object:Gem::Requirement
181
- requirements:
182
- - - "~>"
183
- - !ruby/object:Gem::Version
184
- version: '1.0'
185
- - !ruby/object:Gem::Dependency
186
- name: rake
187
- requirement: !ruby/object:Gem::Requirement
188
- requirements:
189
- - - "~>"
190
- - !ruby/object:Gem::Version
191
- version: '10.4'
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: 10.4.2
195
- type: :development
196
- prerelease: false
197
- version_requirements: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - "~>"
200
- - !ruby/object:Gem::Version
201
- version: '10.4'
202
- - - ">="
203
- - !ruby/object:Gem::Version
204
- version: 10.4.2
205
- - !ruby/object:Gem::Dependency
206
- name: rdoc
207
- requirement: !ruby/object:Gem::Requirement
208
- requirements:
209
- - - "~>"
210
- - !ruby/object:Gem::Version
211
- version: '5.0'
212
- type: :development
213
- prerelease: false
214
- version_requirements: !ruby/object:Gem::Requirement
215
- requirements:
216
- - - "~>"
217
- - !ruby/object:Gem::Version
218
- version: '5.0'
219
- - !ruby/object:Gem::Dependency
220
- name: ruby-prof
221
- requirement: !ruby/object:Gem::Requirement
222
- requirements:
223
- - - "~>"
224
- - !ruby/object:Gem::Version
225
- version: '0.17'
226
- type: :development
227
- prerelease: false
228
- version_requirements: !ruby/object:Gem::Requirement
229
- requirements:
230
- - - "~>"
231
- - !ruby/object:Gem::Version
232
- version: '0.17'
233
- - !ruby/object:Gem::Dependency
234
- name: timecop
235
- requirement: !ruby/object:Gem::Requirement
236
- requirements:
237
- - - "~>"
238
- - !ruby/object:Gem::Version
239
- version: '0.9'
240
- type: :development
241
- prerelease: false
242
- version_requirements: !ruby/object:Gem::Requirement
243
- requirements:
244
- - - "~>"
245
- - !ruby/object:Gem::Version
246
- version: '0.9'
26
+ version: '4'
247
27
  description: Contributed Rack Middleware and Utilities
248
28
  email: rack-devel@googlegroups.com
249
29
  executables: []
@@ -292,11 +72,12 @@ files:
292
72
  - lib/rack/contrib/static_cache.rb
293
73
  - lib/rack/contrib/time_zone.rb
294
74
  - lib/rack/contrib/try_static.rb
75
+ - lib/rack/contrib/version.rb
295
76
  homepage: https://github.com/rack/rack-contrib/
296
77
  licenses:
297
78
  - MIT
298
79
  metadata: {}
299
- post_install_message:
80
+ post_install_message:
300
81
  rdoc_options:
301
82
  - "--line-numbers"
302
83
  - "--inline-source"
@@ -317,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
98
  - !ruby/object:Gem::Version
318
99
  version: '0'
319
100
  requirements: []
320
- rubygems_version: 3.0.3
321
- signing_key:
101
+ rubygems_version: 3.5.3
102
+ signing_key:
322
103
  specification_version: 2
323
104
  summary: Contributed Rack Middleware and Utilities
324
105
  test_files: []