rack-contrib 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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: []