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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +292 -74
- data/CONTRIBUTING.md +53 -47
- data/MIT-LICENSE +1 -1
- data/README.md +336 -0
- data/SPEC.rdoc +174 -126
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +3 -1
- data/lib/rack/auth/basic.rb +2 -3
- data/lib/rack/auth/digest/md5.rb +1 -131
- data/lib/rack/auth/digest/nonce.rb +1 -53
- data/lib/rack/auth/digest/params.rb +1 -54
- data/lib/rack/auth/digest/request.rb +1 -43
- data/lib/rack/auth/digest.rb +256 -0
- data/lib/rack/body_proxy.rb +21 -3
- data/lib/rack/builder.rb +83 -63
- data/lib/rack/cascade.rb +2 -0
- data/lib/rack/chunked.rb +16 -13
- data/lib/rack/common_logger.rb +22 -17
- data/lib/rack/conditional_get.rb +18 -15
- data/lib/rack/constants.rb +64 -0
- data/lib/rack/content_length.rb +12 -16
- data/lib/rack/content_type.rb +8 -5
- data/lib/rack/deflater.rb +40 -26
- data/lib/rack/directory.rb +9 -3
- data/lib/rack/etag.rb +17 -23
- data/lib/rack/events.rb +4 -0
- data/lib/rack/file.rb +2 -0
- data/lib/rack/files.rb +15 -17
- data/lib/rack/head.rb +9 -8
- data/lib/rack/headers.rb +154 -0
- data/lib/rack/lint.rb +758 -646
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +3 -8
- data/lib/rack/method_override.rb +5 -1
- data/lib/rack/mime.rb +8 -0
- data/lib/rack/mock.rb +1 -300
- data/lib/rack/mock_request.rb +166 -0
- data/lib/rack/mock_response.rb +155 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +127 -69
- data/lib/rack/multipart/uploaded_file.rb +4 -0
- data/lib/rack/multipart.rb +20 -40
- data/lib/rack/null_logger.rb +9 -0
- data/lib/rack/query_parser.rb +78 -46
- data/lib/rack/recursive.rb +2 -0
- data/lib/rack/reloader.rb +0 -2
- data/lib/rack/request.rb +224 -106
- data/lib/rack/response.rb +138 -61
- data/lib/rack/rewindable_input.rb +24 -5
- data/lib/rack/runtime.rb +7 -6
- data/lib/rack/sendfile.rb +30 -25
- data/lib/rack/show_exceptions.rb +15 -2
- data/lib/rack/show_status.rb +17 -7
- data/lib/rack/static.rb +8 -8
- data/lib/rack/tempfile_reaper.rb +15 -4
- data/lib/rack/urlmap.rb +3 -1
- data/lib/rack/utils.rb +206 -180
- data/lib/rack/version.rb +9 -4
- data/lib/rack.rb +13 -87
- metadata +15 -35
- data/README.rdoc +0 -347
- data/Rakefile +0 -130
- data/bin/rackup +0 -5
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +0 -150
- data/contrib/rack_logo.svg +0 -164
- data/contrib/rdoc.css +0 -412
- data/example/lobster.ru +0 -6
- data/example/protectedlobster.rb +0 -16
- data/example/protectedlobster.ru +0 -10
- data/lib/rack/core_ext/regexp.rb +0 -14
- data/lib/rack/handler/cgi.rb +0 -59
- data/lib/rack/handler/fastcgi.rb +0 -100
- data/lib/rack/handler/lsws.rb +0 -61
- data/lib/rack/handler/scgi.rb +0 -71
- data/lib/rack/handler/thin.rb +0 -36
- data/lib/rack/handler/webrick.rb +0 -129
- data/lib/rack/handler.rb +0 -104
- data/lib/rack/lobster.rb +0 -70
- data/lib/rack/server.rb +0 -466
- data/lib/rack/session/abstract/id.rb +0 -523
- data/lib/rack/session/cookie.rb +0 -203
- data/lib/rack/session/memcache.rb +0 -10
- data/lib/rack/session/pool.rb +0 -90
- 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", { '
|
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, { '
|
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 = { "
|
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]["
|
92
|
+
response[1]["content-range"] = "bytes */#{size}"
|
95
93
|
return response
|
96
|
-
|
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["
|
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
|
-
|
168
|
-
|
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
|
-
"
|
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
|
-
|
15
|
+
_, _, body = response = @app.call(env)
|
13
16
|
|
14
17
|
if env[REQUEST_METHOD] == HEAD
|
15
|
-
[
|
16
|
-
|
17
|
-
|
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
|
data/lib/rack/headers.rb
ADDED
@@ -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
|