rack-contrib 2.2.0 → 2.4.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-contrib might be problematic. Click here for more details.

Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -1
  3. data/lib/rack/contrib/access.rb +8 -6
  4. data/lib/rack/contrib/backstage.rb +5 -3
  5. data/lib/rack/contrib/bounce_favicon.rb +3 -1
  6. data/lib/rack/contrib/callbacks.rb +2 -0
  7. data/lib/rack/contrib/common_cookies.rb +19 -11
  8. data/lib/rack/contrib/config.rb +3 -15
  9. data/lib/rack/contrib/cookies.rb +2 -0
  10. data/lib/rack/contrib/csshttprequest.rb +11 -5
  11. data/lib/rack/contrib/deflect.rb +35 -33
  12. data/lib/rack/contrib/enforce_valid_encoding.rb +3 -1
  13. data/lib/rack/contrib/evil.rb +2 -0
  14. data/lib/rack/contrib/expectation_cascade.rb +5 -3
  15. data/lib/rack/contrib/garbagecollector.rb +2 -0
  16. data/lib/rack/contrib/host_meta.rb +3 -1
  17. data/lib/rack/contrib/json_body_parser.rb +22 -11
  18. data/lib/rack/contrib/jsonp.rb +12 -7
  19. data/lib/rack/contrib/lazy_conditional_get.rb +13 -4
  20. data/lib/rack/contrib/lighttpd_script_name_fix.rb +2 -0
  21. data/lib/rack/contrib/locale.rb +6 -0
  22. data/lib/rack/contrib/mailexceptions.rb +2 -0
  23. data/lib/rack/contrib/nested_params.rb +3 -1
  24. data/lib/rack/contrib/not_found.rb +3 -1
  25. data/lib/rack/contrib/post_body_content_type_parser.rb +4 -2
  26. data/lib/rack/contrib/printout.rb +3 -1
  27. data/lib/rack/contrib/proctitle.rb +2 -0
  28. data/lib/rack/contrib/profiler.rb +17 -14
  29. data/lib/rack/contrib/relative_redirect.rb +11 -5
  30. data/lib/rack/contrib/response_cache.rb +13 -11
  31. data/lib/rack/contrib/response_headers.rb +8 -2
  32. data/lib/rack/contrib/route_exceptions.rb +2 -0
  33. data/lib/rack/contrib/runtime.rb +3 -30
  34. data/lib/rack/contrib/signals.rb +6 -0
  35. data/lib/rack/contrib/simple_endpoint.rb +3 -1
  36. data/lib/rack/contrib/static_cache.rb +13 -4
  37. data/lib/rack/contrib/time_zone.rb +2 -0
  38. data/lib/rack/contrib/try_static.rb +2 -0
  39. data/lib/rack/contrib/version.rb +5 -0
  40. data/lib/rack/contrib.rb +2 -1
  41. metadata +10 -229
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
4
  require 'json'
3
5
  rescue LoadError => e
@@ -73,7 +75,7 @@ module Rack
73
75
 
74
76
  def call(env)
75
77
  if Rack::Request.new(env).media_type == APPLICATION_JSON && (body = env[POST_BODY].read).length != 0
76
- 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
77
79
  env.update(FORM_HASH => @block.call(body), FORM_INPUT => env[POST_BODY])
78
80
  end
79
81
  @app.call(env)
@@ -82,7 +84,7 @@ module Rack
82
84
  end
83
85
 
84
86
  def bad_request(body = 'Bad Request')
85
- [ 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] ]
86
88
  end
87
89
  end
88
90
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  #prints the environment and request for simple debugging
3
5
  class Printout
@@ -6,7 +8,7 @@ module Rack
6
8
  end
7
9
 
8
10
  def call(env)
9
- # See http://rack.rubyforge.org/doc/SPEC.html for details
11
+ # See https://github.com/rack/rack/blob/main/SPEC.rdoc for details
10
12
  puts "**********\n Environment\n **************"
11
13
  puts env.inspect
12
14
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Middleware to update the process title ($0) with information about the
3
5
  # current request. Based loosely on:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ruby-prof'
2
4
 
3
5
  module Rack
@@ -30,6 +32,7 @@ module Rack
30
32
  # option defaulting to :call_stack.
31
33
  def initialize(app, options = {})
32
34
  @app = app
35
+ @profile = nil
33
36
  @printer = parse_printer(options[:printer] || DEFAULT_PRINTER)
34
37
  @times = (options[:times] || 1).to_i
35
38
  end
@@ -44,27 +47,27 @@ module Rack
44
47
 
45
48
  private
46
49
  def profiling?(env)
47
- unless ::RubyProf.running?
48
- request = Rack::Request.new(env.clone)
49
- if mode = request.params.delete('profile')
50
- if ::RubyProf.const_defined?(mode.upcase)
51
- mode
52
- else
53
- env['rack.errors'].write "Invalid RubyProf measure_mode: " +
54
- "#{mode}. Use one of #{MODES.to_a.join(', ')}"
55
- false
56
- end
50
+ return if @profile && @profile.running?
51
+
52
+ request = Rack::Request.new(env.clone)
53
+ if mode = request.params.delete('profile')
54
+ if ::RubyProf.const_defined?(mode.upcase)
55
+ mode
56
+ else
57
+ env['rack.errors'].write "Invalid RubyProf measure_mode: " +
58
+ "#{mode}. Use one of #{MODES.to_a.join(', ')}"
59
+ false
57
60
  end
58
61
  end
59
62
  end
60
63
 
61
64
  def profile(env, mode)
62
- ::RubyProf.measure_mode = ::RubyProf.const_get(mode.upcase)
65
+ @profile = ::RubyProf::Profile.new(measure_mode: ::RubyProf.const_get(mode.upcase))
63
66
 
64
67
  GC.enable_stats if GC.respond_to?(:enable_stats)
65
68
  request = Rack::Request.new(env.clone)
66
69
  runs = (request.params['profiler_runs'] || @times).to_i
67
- result = ::RubyProf.profile do
70
+ result = @profile.profile do
68
71
  runs.times { @app.call(env) }
69
72
  end
70
73
  GC.disable_stats if GC.respond_to?(:disable_stats)
@@ -80,10 +83,10 @@ module Rack
80
83
  end
81
84
 
82
85
  def headers(printer, env, mode)
83
- headers = { 'Content-Type' => CONTENT_TYPES[printer.name] }
86
+ headers = { 'content-type' => CONTENT_TYPES[printer.name] }
84
87
  if printer == ::RubyProf::CallTreePrinter
85
88
  filename = ::File.basename(env['PATH_INFO'])
86
- headers['Content-Disposition'] =
89
+ headers['content-disposition'] =
87
90
  %(attachment; filename="#{filename}.#{mode}.tree")
88
91
  end
89
92
  headers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack'
2
4
 
3
5
  # Rack::RelativeRedirect is a simple middleware that converts relative paths in
@@ -30,15 +32,19 @@ class Rack::RelativeRedirect
30
32
  # and use that to make the Location header an absolute url. If the Location
31
33
  # does not start with a slash, make location relative to the path requested.
32
34
  def call(env)
33
- res = @app.call(env)
34
- if [301,302,303, 307,308].include?(res[0]) and loc = res[1]['Location'] and !%r{\Ahttps?://}o.match(loc)
35
- absolute = @absolute_proc.call(env, res)
36
- res[1]['Location'] = if %r{\A/}.match(loc)
35
+ status, headers, body = @app.call(env)
36
+ headers_klass = Rack.release < "3" ? Rack::Utils::HeaderHash : Rack::Headers
37
+ headers = headers_klass.new.merge(headers)
38
+
39
+ if [301,302,303, 307,308].include?(status) and loc = headers['Location'] and !%r{\Ahttps?://}o.match(loc)
40
+ absolute = @absolute_proc.call(env, [status, headers, body])
41
+ headers['Location'] = if %r{\A/}.match(loc)
37
42
  "#{absolute}#{loc}"
38
43
  else
39
44
  "#{absolute}#{File.dirname(Rack::Utils.unescape(env['PATH_INFO']))}/#{loc}"
40
45
  end
41
46
  end
42
- res
47
+
48
+ [status, headers, body]
43
49
  end
44
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fileutils'
2
4
  require 'rack'
3
5
 
@@ -19,12 +21,8 @@ class Rack::ResponseCache
19
21
  DEFAULT_PATH_PROC = proc do |env, res|
20
22
  path = Rack::Utils.unescape(env['PATH_INFO'])
21
23
  headers = res[1]
22
- # Content-Type is almost always at headers['Content-Type'], but to fully
23
- # comply with HTTP RFC 7230, we fall back to a case-insensitive lookup
24
- content_type = headers.fetch('Content-Type') do |titlecase_key|
25
- _, val = headers.find { |key, _| key.casecmp(titlecase_key) == 0 }
26
- val
27
- end
24
+ content_type = headers['Content-Type']
25
+
28
26
  if !path.include?('..') and match = /text\/((?:x|ht)ml|css)/o.match(content_type)
29
27
  type = match[1]
30
28
  path = "#{path}.#{type}" unless /\.#{type}\z/.match(path)
@@ -54,16 +52,20 @@ class Rack::ResponseCache
54
52
  # If the cache is a string, create any necessary middle directories, and cache the file in the appropriate
55
53
  # subdirectory of cache. Otherwise, cache the body of the response as the value with the path as the key.
56
54
  def call(env)
57
- res = @app.call(env)
58
- if env['REQUEST_METHOD'] == 'GET' and env['QUERY_STRING'] == '' and res[0] == 200 and path = @path_proc.call(env, res)
55
+ status, headers, body = @app.call(env)
56
+ headers_klass = Rack.release < "3" ? Rack::Utils::HeaderHash : Rack::Headers
57
+ headers = headers_klass.new.merge(headers)
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)
60
61
  path = File.join(@cache, path) if @cache
61
62
  FileUtils.mkdir_p(File.dirname(path))
62
- File.open(path, 'wb'){|f| res[2].each{|c| f.write(c)}}
63
+ File.open(path, 'wb'){|f| body.each{|c| f.write(c)}}
63
64
  else
64
- @cache[path] = res[2]
65
+ @cache[path] = body
65
66
  end
66
67
  end
67
- res
68
+
69
+ [status, headers, body]
68
70
  end
69
71
  end
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Allows you to tap into the response headers. Yields a Rack::Utils::HeaderHash
3
- # 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:
4
7
  #
5
8
  # use Rack::ResponseHeaders do |headers|
6
9
  # headers['X-Foo'] = 'bar'
@@ -8,6 +11,9 @@ module Rack
8
11
  # end
9
12
  #
10
13
  class ResponseHeaders
14
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
15
+ private_constant :HEADERS_KLASS
16
+
11
17
  def initialize(app, &block)
12
18
  @app = app
13
19
  @block = block
@@ -15,7 +21,7 @@ module Rack
15
21
 
16
22
  def call(env)
17
23
  response = @app.call(env)
18
- headers = Utils::HeaderHash.new(response[1])
24
+ headers = HEADERS_KLASS.new.merge(response[1])
19
25
  @block.call(headers)
20
26
  response[1] = headers
21
27
  response
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  class RouteExceptions
3
5
  ROUTES = [
@@ -1,31 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
- module Rack
3
- # Sets an "X-Runtime" response header, indicating the response
4
- # time of the request, in seconds
5
- #
6
- # You can put it right before the application to see the processing
7
- # time, or before all the other middlewares to include time for them,
8
- # too.
9
- class Runtime
10
- def initialize(app, name = nil)
11
- @app = app
12
- @header_name = "X-Runtime"
13
- @header_name << "-#{name}" if name
14
- end
15
-
16
- def call(env)
17
- start_time = Time.now
18
- status, headers, body = @app.call(env)
19
- request_time = Time.now - start_time
20
-
21
- if !headers.has_key?(@header_name)
22
- headers[@header_name] = "%0.6f" % request_time
23
- end
24
-
25
- [status, headers, body]
26
- end
27
- end
28
- end
29
-
30
-
31
-
3
+ require 'rack'
4
+ require 'rack/runtime'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Installs signal handlers that are safely processed after a request
3
5
  #
@@ -24,6 +26,10 @@ module Rack
24
26
  @body.each(&block)
25
27
  @callback.call
26
28
  end
29
+
30
+ def close
31
+ @body.close if @body.respond_to?(:close)
32
+ end
27
33
  end
28
34
 
29
35
  def initialize(app, &block)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Create simple endpoints with routing rules, similar to Sinatra actions.
3
5
  #
@@ -78,4 +80,4 @@ module Rack
78
80
  @verbs.empty? || @verbs.include?(method)
79
81
  end
80
82
  end
81
- end
83
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'time'
2
4
 
3
5
  module Rack
@@ -50,6 +52,8 @@ module Rack
50
52
 
51
53
 
52
54
  class StaticCache
55
+ HEADERS_KLASS = Rack.release < "3" ? Utils::HeaderHash : Headers
56
+ private_constant :HEADERS_KLASS
53
57
 
54
58
  def initialize(app, options={})
55
59
  @app = app
@@ -57,13 +61,15 @@ module Rack
57
61
  @no_cache = {}
58
62
  @urls.collect! do |url|
59
63
  if url =~ /\*$/
60
- url.sub!(/\*$/, '')
61
- @no_cache[url] = 1
64
+ url_prefix = url.sub(/\*$/, '')
65
+ @no_cache[url_prefix] = 1
66
+ url_prefix
67
+ else
68
+ url
62
69
  end
63
- url
64
70
  end
65
71
  root = options[:root] || Dir.pwd
66
- @file_server = Rack::File.new(root)
72
+ @file_server = Rack::Files.new(root)
67
73
  @cache_duration = options[:duration] || 1
68
74
  @versioning_enabled = options.fetch(:versioning, true)
69
75
  if @versioning_enabled
@@ -81,7 +87,10 @@ module Rack
81
87
  if @versioning_enabled
82
88
  path.sub!(@version_regex, '\1')
83
89
  end
90
+
84
91
  status, headers, body = @file_server.call(env)
92
+ headers = HEADERS_KLASS.new.merge(headers)
93
+
85
94
  if @no_cache[url].nil?
86
95
  headers['Cache-Control'] ="max-age=#{@duration_in_seconds}, public"
87
96
  headers['Expires'] = duration_in_words
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  class TimeZone
3
5
  Javascript = <<-EOJ
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
 
3
5
  # The Rack::TryStatic middleware delegates requests to Rack::Static middleware
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ module Contrib
3
+ VERSION = '2.4.0'
4
+ end
5
+ end
data/lib/rack/contrib.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack'
2
4
 
3
5
  module Rack
@@ -33,7 +35,6 @@ module Rack
33
35
  autoload :ProcTitle, "rack/contrib/proctitle"
34
36
  autoload :Profiler, "rack/contrib/profiler"
35
37
  autoload :ResponseHeaders, "rack/contrib/response_headers"
36
- autoload :Runtime, "rack/contrib/runtime"
37
38
  autoload :Signals, "rack/contrib/signals"
38
39
  autoload :SimpleEndpoint, "rack/contrib/simple_endpoint"
39
40
  autoload :TimeZone, "rack/contrib/time_zone"
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.2.0
4
+ version: 2.4.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-03-29 00:00:00.000000000 Z
11
+ date: 2023-10-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.4.10
102
+ signing_key:
322
103
  specification_version: 2
323
104
  summary: Contributed Rack Middleware and Utilities
324
105
  test_files: []