rack 2.2.17 → 3.0.18

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 might be problematic. Click here for more details.

Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +292 -74
  3. data/CONTRIBUTING.md +53 -47
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +336 -0
  6. data/SPEC.rdoc +174 -126
  7. data/lib/rack/auth/abstract/handler.rb +3 -1
  8. data/lib/rack/auth/abstract/request.rb +3 -1
  9. data/lib/rack/auth/basic.rb +2 -3
  10. data/lib/rack/auth/digest/md5.rb +1 -131
  11. data/lib/rack/auth/digest/nonce.rb +1 -53
  12. data/lib/rack/auth/digest/params.rb +1 -54
  13. data/lib/rack/auth/digest/request.rb +1 -43
  14. data/lib/rack/auth/digest.rb +256 -0
  15. data/lib/rack/body_proxy.rb +21 -3
  16. data/lib/rack/builder.rb +83 -63
  17. data/lib/rack/cascade.rb +2 -0
  18. data/lib/rack/chunked.rb +16 -13
  19. data/lib/rack/common_logger.rb +22 -17
  20. data/lib/rack/conditional_get.rb +18 -15
  21. data/lib/rack/constants.rb +64 -0
  22. data/lib/rack/content_length.rb +12 -16
  23. data/lib/rack/content_type.rb +8 -5
  24. data/lib/rack/deflater.rb +40 -26
  25. data/lib/rack/directory.rb +9 -3
  26. data/lib/rack/etag.rb +17 -23
  27. data/lib/rack/events.rb +4 -0
  28. data/lib/rack/file.rb +2 -0
  29. data/lib/rack/files.rb +15 -17
  30. data/lib/rack/head.rb +9 -8
  31. data/lib/rack/headers.rb +154 -0
  32. data/lib/rack/lint.rb +758 -646
  33. data/lib/rack/lock.rb +2 -5
  34. data/lib/rack/logger.rb +2 -0
  35. data/lib/rack/media_type.rb +3 -8
  36. data/lib/rack/method_override.rb +5 -1
  37. data/lib/rack/mime.rb +8 -0
  38. data/lib/rack/mock.rb +1 -300
  39. data/lib/rack/mock_request.rb +166 -0
  40. data/lib/rack/mock_response.rb +155 -0
  41. data/lib/rack/multipart/generator.rb +7 -5
  42. data/lib/rack/multipart/parser.rb +127 -69
  43. data/lib/rack/multipart/uploaded_file.rb +4 -0
  44. data/lib/rack/multipart.rb +20 -40
  45. data/lib/rack/null_logger.rb +9 -0
  46. data/lib/rack/query_parser.rb +78 -46
  47. data/lib/rack/recursive.rb +2 -0
  48. data/lib/rack/reloader.rb +0 -2
  49. data/lib/rack/request.rb +224 -106
  50. data/lib/rack/response.rb +138 -61
  51. data/lib/rack/rewindable_input.rb +24 -5
  52. data/lib/rack/runtime.rb +7 -6
  53. data/lib/rack/sendfile.rb +30 -25
  54. data/lib/rack/show_exceptions.rb +15 -2
  55. data/lib/rack/show_status.rb +17 -7
  56. data/lib/rack/static.rb +8 -8
  57. data/lib/rack/tempfile_reaper.rb +15 -4
  58. data/lib/rack/urlmap.rb +3 -1
  59. data/lib/rack/utils.rb +206 -180
  60. data/lib/rack/version.rb +9 -4
  61. data/lib/rack.rb +13 -87
  62. metadata +15 -35
  63. data/README.rdoc +0 -347
  64. data/Rakefile +0 -130
  65. data/bin/rackup +0 -5
  66. data/contrib/rack.png +0 -0
  67. data/contrib/rack.svg +0 -150
  68. data/contrib/rack_logo.svg +0 -164
  69. data/contrib/rdoc.css +0 -412
  70. data/example/lobster.ru +0 -6
  71. data/example/protectedlobster.rb +0 -16
  72. data/example/protectedlobster.ru +0 -10
  73. data/lib/rack/core_ext/regexp.rb +0 -14
  74. data/lib/rack/handler/cgi.rb +0 -59
  75. data/lib/rack/handler/fastcgi.rb +0 -100
  76. data/lib/rack/handler/lsws.rb +0 -61
  77. data/lib/rack/handler/scgi.rb +0 -71
  78. data/lib/rack/handler/thin.rb +0 -36
  79. data/lib/rack/handler/webrick.rb +0 -129
  80. data/lib/rack/handler.rb +0 -104
  81. data/lib/rack/lobster.rb +0 -70
  82. data/lib/rack/server.rb +0 -466
  83. data/lib/rack/session/abstract/id.rb +0 -523
  84. data/lib/rack/session/cookie.rb +0 -203
  85. data/lib/rack/session/memcache.rb +0 -10
  86. data/lib/rack/session/pool.rb +0 -90
  87. data/rack.gemspec +0 -46
data/lib/rack/files.rb CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  require 'time'
4
4
 
5
+ require_relative 'constants'
6
+ require_relative 'head'
7
+ require_relative 'utils'
8
+ require_relative 'request'
9
+ require_relative 'mime'
10
+
5
11
  module Rack
6
12
  # Rack::Files serves files below the +root+ directory given, according to the
7
13
  # path info of the Rack request.
@@ -16,14 +22,6 @@ module Rack
16
22
  ALLOW_HEADER = ALLOWED_VERBS.join(', ')
17
23
  MULTIPART_BOUNDARY = 'AaB03x'
18
24
 
19
- # @todo remove in 3.0
20
- def self.method_added(name)
21
- if name == :response_body
22
- raise "#{self.class}\#response_body is no longer supported."
23
- end
24
- super
25
- end
26
-
27
25
  attr_reader :root
28
26
 
29
27
  def initialize(root, headers = {}, default_mime = 'text/plain')
@@ -41,7 +39,7 @@ module Rack
41
39
  def get(env)
42
40
  request = Rack::Request.new env
43
41
  unless ALLOWED_VERBS.include? request.request_method
44
- return fail(405, "Method Not Allowed", { 'Allow' => ALLOW_HEADER })
42
+ return fail(405, "Method Not Allowed", { 'allow' => ALLOW_HEADER })
45
43
  end
46
44
 
47
45
  path_info = Utils.unescape_path request.path_info
@@ -69,12 +67,12 @@ module Rack
69
67
 
70
68
  def serving(request, path)
71
69
  if request.options?
72
- return [200, { 'Allow' => ALLOW_HEADER, CONTENT_LENGTH => '0' }, []]
70
+ return [200, { 'allow' => ALLOW_HEADER, CONTENT_LENGTH => '0' }, []]
73
71
  end
74
72
  last_modified = ::File.mtime(path).httpdate
75
73
  return [304, {}, []] if request.get_header('HTTP_IF_MODIFIED_SINCE') == last_modified
76
74
 
77
- headers = { "Last-Modified" => last_modified }
75
+ headers = { "last-modified" => last_modified }
78
76
  mime_type = mime_type path, @default_mime
79
77
  headers[CONTENT_TYPE] = mime_type if mime_type
80
78
 
@@ -91,15 +89,15 @@ module Rack
91
89
  elsif ranges.empty?
92
90
  # Unsatisfiable. Return error, and file size:
93
91
  response = fail(416, "Byte range unsatisfiable")
94
- response[1]["Content-Range"] = "bytes */#{size}"
92
+ response[1]["content-range"] = "bytes */#{size}"
95
93
  return response
96
- elsif ranges.size >= 1
94
+ else
97
95
  # Partial content
98
96
  partial_content = true
99
97
 
100
98
  if ranges.size == 1
101
99
  range = ranges[0]
102
- headers["Content-Range"] = "bytes #{range.begin}-#{range.end}/#{size}"
100
+ headers["content-range"] = "bytes #{range.begin}-#{range.end}/#{size}"
103
101
  else
104
102
  headers[CONTENT_TYPE] = "multipart/byteranges; boundary=#{MULTIPART_BOUNDARY}"
105
103
  end
@@ -164,8 +162,8 @@ module Rack
164
162
  <<-EOF
165
163
  \r
166
164
  --#{MULTIPART_BOUNDARY}\r
167
- Content-Type: #{options[:mime_type]}\r
168
- Content-Range: bytes #{range.begin}-#{range.end}/#{options[:size]}\r
165
+ content-type: #{options[:mime_type]}\r
166
+ content-range: bytes #{range.begin}-#{range.end}/#{options[:size]}\r
169
167
  \r
170
168
  EOF
171
169
  end
@@ -197,7 +195,7 @@ EOF
197
195
  {
198
196
  CONTENT_TYPE => "text/plain",
199
197
  CONTENT_LENGTH => body.size.to_s,
200
- "X-Cascade" => "pass"
198
+ "x-cascade" => "pass"
201
199
  }.merge!(headers),
202
200
  [body]
203
201
  ]
data/lib/rack/head.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'constants'
4
+ require_relative 'body_proxy'
5
+
3
6
  module Rack
4
7
  # Rack::Head returns an empty body for all HEAD requests. It leaves
5
8
  # all other requests unchanged.
@@ -9,17 +12,15 @@ module Rack
9
12
  end
10
13
 
11
14
  def call(env)
12
- status, headers, body = @app.call(env)
15
+ _, _, body = response = @app.call(env)
13
16
 
14
17
  if env[REQUEST_METHOD] == HEAD
15
- [
16
- status, headers, Rack::BodyProxy.new([]) do
17
- body.close if body.respond_to? :close
18
- end
19
- ]
20
- else
21
- [status, headers, body]
18
+ response[2] = Rack::BodyProxy.new([]) do
19
+ body.close if body.respond_to? :close
20
+ end
22
21
  end
22
+
23
+ response
23
24
  end
24
25
  end
25
26
  end
@@ -0,0 +1,154 @@
1
+ module Rack
2
+ # Rack::Headers is a Hash subclass that downcases all keys. It's designed
3
+ # to be used by rack applications that don't implement the Rack 3 SPEC
4
+ # (by using non-lowercase response header keys), automatically handling
5
+ # the downcasing of keys.
6
+ class Headers < Hash
7
+ def self.[](*items)
8
+ if items.length % 2 != 0
9
+ if items.length == 1 && items.first.is_a?(Hash)
10
+ new.merge!(items.first)
11
+ else
12
+ raise ArgumentError, "odd number of arguments for Rack::Headers"
13
+ end
14
+ else
15
+ hash = new
16
+ loop do
17
+ break if items.length == 0
18
+ key = items.shift
19
+ value = items.shift
20
+ hash[key] = value
21
+ end
22
+ hash
23
+ end
24
+ end
25
+
26
+ def [](key)
27
+ super(downcase_key(key))
28
+ end
29
+
30
+ def []=(key, value)
31
+ super(key.downcase.freeze, value)
32
+ end
33
+ alias store []=
34
+
35
+ def assoc(key)
36
+ super(downcase_key(key))
37
+ end
38
+
39
+ def compare_by_identity
40
+ raise TypeError, "Rack::Headers cannot compare by identity, use regular Hash"
41
+ end
42
+
43
+ def delete(key)
44
+ super(downcase_key(key))
45
+ end
46
+
47
+ def dig(key, *a)
48
+ super(downcase_key(key), *a)
49
+ end
50
+
51
+ def fetch(key, *default, &block)
52
+ key = downcase_key(key)
53
+ super
54
+ end
55
+
56
+ def fetch_values(*a)
57
+ super(*a.map!{|key| downcase_key(key)})
58
+ end
59
+
60
+ def has_key?(key)
61
+ super(downcase_key(key))
62
+ end
63
+ alias include? has_key?
64
+ alias key? has_key?
65
+ alias member? has_key?
66
+
67
+ def invert
68
+ hash = self.class.new
69
+ each{|key, value| hash[value] = key}
70
+ hash
71
+ end
72
+
73
+ def merge(hash, &block)
74
+ dup.merge!(hash, &block)
75
+ end
76
+
77
+ def reject(&block)
78
+ hash = dup
79
+ hash.reject!(&block)
80
+ hash
81
+ end
82
+
83
+ def replace(hash)
84
+ clear
85
+ update(hash)
86
+ end
87
+
88
+ def select(&block)
89
+ hash = dup
90
+ hash.select!(&block)
91
+ hash
92
+ end
93
+
94
+ def to_proc
95
+ lambda{|x| self[x]}
96
+ end
97
+
98
+ def transform_values(&block)
99
+ dup.transform_values!(&block)
100
+ end
101
+
102
+ def update(hash, &block)
103
+ hash.each do |key, value|
104
+ self[key] = if block_given? && include?(key)
105
+ block.call(key, self[key], value)
106
+ else
107
+ value
108
+ end
109
+ end
110
+ self
111
+ end
112
+ alias merge! update
113
+
114
+ def values_at(*keys)
115
+ keys.map{|key| self[key]}
116
+ end
117
+
118
+ # :nocov:
119
+ if RUBY_VERSION >= '2.5'
120
+ # :nocov:
121
+ def slice(*a)
122
+ h = self.class.new
123
+ a.each{|k| h[k] = self[k] if has_key?(k)}
124
+ h
125
+ end
126
+
127
+ def transform_keys(&block)
128
+ dup.transform_keys!(&block)
129
+ end
130
+
131
+ def transform_keys!
132
+ hash = self.class.new
133
+ each do |k, v|
134
+ hash[yield k] = v
135
+ end
136
+ replace(hash)
137
+ end
138
+ end
139
+
140
+ # :nocov:
141
+ if RUBY_VERSION >= '3.0'
142
+ # :nocov:
143
+ def except(*a)
144
+ super(*a.map!{|key| downcase_key(key)})
145
+ end
146
+ end
147
+
148
+ private
149
+
150
+ def downcase_key(key)
151
+ key.is_a?(String) ? key.downcase : key
152
+ end
153
+ end
154
+ end