rack 2.2.23 → 3.2.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +554 -83
- data/CONTRIBUTING.md +63 -55
- data/MIT-LICENSE +1 -1
- data/README.md +384 -0
- data/SPEC.rdoc +243 -277
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +5 -1
- data/lib/rack/auth/basic.rb +1 -3
- data/lib/rack/bad_request.rb +8 -0
- data/lib/rack/body_proxy.rb +21 -3
- data/lib/rack/builder.rb +108 -69
- data/lib/rack/cascade.rb +2 -3
- data/lib/rack/common_logger.rb +22 -17
- data/lib/rack/conditional_get.rb +20 -16
- data/lib/rack/constants.rb +68 -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 +10 -4
- data/lib/rack/etag.rb +17 -23
- data/lib/rack/events.rb +25 -6
- data/lib/rack/files.rb +16 -18
- data/lib/rack/head.rb +8 -8
- data/lib/rack/headers.rb +238 -0
- data/lib/rack/lint.rb +817 -648
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/media_type.rb +6 -7
- data/lib/rack/method_override.rb +5 -1
- data/lib/rack/mime.rb +14 -5
- data/lib/rack/mock.rb +1 -300
- data/lib/rack/mock_request.rb +161 -0
- data/lib/rack/mock_response.rb +156 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +240 -123
- data/lib/rack/multipart/uploaded_file.rb +45 -4
- data/lib/rack/multipart.rb +53 -40
- data/lib/rack/null_logger.rb +9 -0
- data/lib/rack/query_parser.rb +116 -121
- data/lib/rack/recursive.rb +2 -0
- data/lib/rack/reloader.rb +0 -2
- data/lib/rack/request.rb +272 -144
- data/lib/rack/response.rb +151 -66
- data/lib/rack/rewindable_input.rb +27 -5
- data/lib/rack/runtime.rb +7 -6
- data/lib/rack/sendfile.rb +37 -32
- data/lib/rack/show_exceptions.rb +25 -6
- data/lib/rack/show_status.rb +17 -9
- data/lib/rack/static.rb +11 -15
- data/lib/rack/tempfile_reaper.rb +15 -4
- data/lib/rack/urlmap.rb +3 -1
- data/lib/rack/utils.rb +234 -275
- data/lib/rack/version.rb +3 -15
- data/lib/rack.rb +13 -90
- metadata +15 -41
- data/README.rdoc +0 -355
- 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/auth/digest/md5.rb +0 -131
- data/lib/rack/auth/digest/nonce.rb +0 -53
- data/lib/rack/auth/digest/params.rb +0 -54
- data/lib/rack/auth/digest/request.rb +0 -43
- data/lib/rack/chunked.rb +0 -117
- data/lib/rack/core_ext/regexp.rb +0 -14
- data/lib/rack/file.rb +0 -7
- 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 -34
- 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/logger.rb +0 -20
- 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/show_exceptions.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'ostruct'
|
|
4
3
|
require 'erb'
|
|
5
4
|
|
|
5
|
+
require_relative 'constants'
|
|
6
|
+
require_relative 'utils'
|
|
7
|
+
require_relative 'request'
|
|
8
|
+
|
|
6
9
|
module Rack
|
|
7
10
|
# Rack::ShowExceptions catches all exceptions raised from the app it
|
|
8
11
|
# wraps. It shows a useful backtrace with the sourcefile and
|
|
@@ -15,6 +18,11 @@ module Rack
|
|
|
15
18
|
class ShowExceptions
|
|
16
19
|
CONTEXT = 7
|
|
17
20
|
|
|
21
|
+
Frame = Struct.new(:filename, :lineno, :function,
|
|
22
|
+
:pre_context_lineno, :pre_context,
|
|
23
|
+
:context_line, :post_context_lineno,
|
|
24
|
+
:post_context)
|
|
25
|
+
|
|
18
26
|
def initialize(app)
|
|
19
27
|
@app = app
|
|
20
28
|
end
|
|
@@ -55,7 +63,16 @@ module Rack
|
|
|
55
63
|
private :accepts_html?
|
|
56
64
|
|
|
57
65
|
def dump_exception(exception)
|
|
58
|
-
|
|
66
|
+
if exception.respond_to?(:detailed_message)
|
|
67
|
+
message = exception.detailed_message(highlight: false)
|
|
68
|
+
# :nocov:
|
|
69
|
+
# Ruby 3.2 added Exception#detailed_message, so the else
|
|
70
|
+
# branch cannot be hit on the current Ruby version.
|
|
71
|
+
else
|
|
72
|
+
message = exception.message
|
|
73
|
+
# :nocov:
|
|
74
|
+
end
|
|
75
|
+
string = "#{exception.class}: #{message}\n".dup
|
|
59
76
|
string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
|
|
60
77
|
string
|
|
61
78
|
end
|
|
@@ -70,7 +87,7 @@ module Rack
|
|
|
70
87
|
# This double assignment is to prevent an "unused variable" warning.
|
|
71
88
|
# Yes, it is dumb, but I don't like Ruby yelling at me.
|
|
72
89
|
frames = frames = exception.backtrace.map { |line|
|
|
73
|
-
frame =
|
|
90
|
+
frame = Frame.new
|
|
74
91
|
if line =~ /(.*?):(\d+)(:in `(.*)')?/
|
|
75
92
|
frame.filename = $1
|
|
76
93
|
frame.lineno = $2.to_i
|
|
@@ -159,7 +176,7 @@ module Rack
|
|
|
159
176
|
div.commands { margin-left: 40px; }
|
|
160
177
|
div.commands a { color:black; text-decoration:none; }
|
|
161
178
|
#summary { background: #ffc; }
|
|
162
|
-
#summary h2 { font-weight: normal; color: #666; }
|
|
179
|
+
#summary h2 { font-family: monospace; font-weight: normal; color: #666; white-space: pre-wrap; }
|
|
163
180
|
#summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; }
|
|
164
181
|
#summary ul#quicklinks li { float: left; padding: 0 1em; }
|
|
165
182
|
#summary ul#quicklinks>li+li { border-left: 1px #666 solid; }
|
|
@@ -227,7 +244,11 @@ module Rack
|
|
|
227
244
|
|
|
228
245
|
<div id="summary">
|
|
229
246
|
<h1><%=h exception.class %> at <%=h path %></h1>
|
|
247
|
+
<% if exception.respond_to?(:detailed_message) %>
|
|
248
|
+
<h2><%=h exception.detailed_message(highlight: false) %></h2>
|
|
249
|
+
<% else %>
|
|
230
250
|
<h2><%=h exception.message %></h2>
|
|
251
|
+
<% end %>
|
|
231
252
|
<table><tr>
|
|
232
253
|
<th>Ruby</th>
|
|
233
254
|
<td>
|
|
@@ -384,7 +405,5 @@ module Rack
|
|
|
384
405
|
</body>
|
|
385
406
|
</html>
|
|
386
407
|
HTML
|
|
387
|
-
|
|
388
|
-
# :startdoc:
|
|
389
408
|
end
|
|
390
409
|
end
|
data/lib/rack/show_status.rb
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
require 'erb'
|
|
4
4
|
|
|
5
|
+
require_relative 'constants'
|
|
6
|
+
require_relative 'utils'
|
|
7
|
+
require_relative 'request'
|
|
8
|
+
require_relative 'body_proxy'
|
|
9
|
+
|
|
5
10
|
module Rack
|
|
6
11
|
# Rack::ShowStatus catches all empty responses and replaces them
|
|
7
12
|
# with a site explaining the error.
|
|
@@ -17,8 +22,7 @@ module Rack
|
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
def call(env)
|
|
20
|
-
status, headers, body = @app.call(env)
|
|
21
|
-
headers = Utils::HeaderHash[headers]
|
|
25
|
+
status, headers, body = response = @app.call(env)
|
|
22
26
|
empty = headers[CONTENT_LENGTH].to_i <= 0
|
|
23
27
|
|
|
24
28
|
# client or server error, or explicit message
|
|
@@ -33,12 +37,18 @@ module Rack
|
|
|
33
37
|
# Yes, it is dumb, but I don't like Ruby yelling at me.
|
|
34
38
|
detail = detail = env[RACK_SHOWSTATUS_DETAIL] || message
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
size =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
html = @template.result(binding)
|
|
41
|
+
size = html.bytesize
|
|
42
|
+
|
|
43
|
+
response[2] = Rack::BodyProxy.new([html]) do
|
|
44
|
+
body.close if body.respond_to?(:close)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
headers[CONTENT_TYPE] = "text/html"
|
|
48
|
+
headers[CONTENT_LENGTH] = size.to_s
|
|
41
49
|
end
|
|
50
|
+
|
|
51
|
+
response
|
|
42
52
|
end
|
|
43
53
|
|
|
44
54
|
def h(obj) # :nodoc:
|
|
@@ -107,7 +117,5 @@ TEMPLATE = <<'HTML'
|
|
|
107
117
|
</body>
|
|
108
118
|
</html>
|
|
109
119
|
HTML
|
|
110
|
-
|
|
111
|
-
# :startdoc:
|
|
112
120
|
end
|
|
113
121
|
end
|
data/lib/rack/static.rb
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'constants'
|
|
4
|
+
require_relative 'files'
|
|
5
|
+
require_relative 'mime'
|
|
6
|
+
|
|
3
7
|
module Rack
|
|
4
8
|
|
|
5
9
|
# The Rack::Static middleware intercepts requests for static files
|
|
@@ -78,22 +82,17 @@ module Rack
|
|
|
78
82
|
# :header_rules => [
|
|
79
83
|
# # Cache all static files in public caches (e.g. Rack::Cache)
|
|
80
84
|
# # as well as in the browser
|
|
81
|
-
# [:all, {'
|
|
85
|
+
# [:all, {'cache-control' => 'public, max-age=31536000'}],
|
|
82
86
|
#
|
|
83
87
|
# # Provide web fonts with cross-origin access-control-headers
|
|
84
88
|
# # Firefox requires this when serving assets using a Content Delivery Network
|
|
85
|
-
# [:fonts, {'
|
|
89
|
+
# [:fonts, {'access-control-allow-origin' => '*'}]
|
|
86
90
|
# ]
|
|
87
91
|
#
|
|
88
92
|
class Static
|
|
89
|
-
(require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
|
|
90
|
-
|
|
91
93
|
def initialize(app, options = {})
|
|
92
94
|
@app = app
|
|
93
95
|
@urls = options[:urls] || ["/favicon.ico"]
|
|
94
|
-
if @urls.kind_of?(Array)
|
|
95
|
-
@urls = @urls.map { |url| [url, url.end_with?('/') ? url : "#{url}/".freeze].freeze }.freeze
|
|
96
|
-
end
|
|
97
96
|
@index = options[:index]
|
|
98
97
|
@gzip = options[:gzip]
|
|
99
98
|
@cascade = options[:cascade]
|
|
@@ -116,7 +115,7 @@ module Rack
|
|
|
116
115
|
end
|
|
117
116
|
|
|
118
117
|
def route_file(path)
|
|
119
|
-
@urls.kind_of?(Array) && @urls.any? { |url
|
|
118
|
+
@urls.kind_of?(Array) && @urls.any? { |url| path.index(url) == 0 }
|
|
120
119
|
end
|
|
121
120
|
|
|
122
121
|
def can_serve(path)
|
|
@@ -141,10 +140,8 @@ module Rack
|
|
|
141
140
|
elsif response[0] == 304
|
|
142
141
|
# Do nothing, leave headers as is
|
|
143
142
|
else
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
end
|
|
147
|
-
response[1]['Content-Encoding'] = 'gzip'
|
|
143
|
+
response[1][CONTENT_TYPE] = Mime.mime_type(::File.extname(path), 'text/plain')
|
|
144
|
+
response[1]['content-encoding'] = 'gzip'
|
|
148
145
|
end
|
|
149
146
|
end
|
|
150
147
|
|
|
@@ -168,8 +165,6 @@ module Rack
|
|
|
168
165
|
|
|
169
166
|
# Convert HTTP header rules to HTTP headers
|
|
170
167
|
def applicable_rules(path)
|
|
171
|
-
path = ::Rack::Utils.unescape_path(path)
|
|
172
|
-
|
|
173
168
|
@header_rules.find_all do |rule, new_headers|
|
|
174
169
|
case rule
|
|
175
170
|
when :all
|
|
@@ -177,9 +172,10 @@ module Rack
|
|
|
177
172
|
when :fonts
|
|
178
173
|
/\.(?:ttf|otf|eot|woff2|woff|svg)\z/.match?(path)
|
|
179
174
|
when String
|
|
175
|
+
path = ::Rack::Utils.unescape(path)
|
|
180
176
|
path.start_with?(rule) || path.start_with?('/' + rule)
|
|
181
177
|
when Array
|
|
182
|
-
|
|
178
|
+
/\.(#{rule.join('|')})\z/.match?(path)
|
|
183
179
|
when Regexp
|
|
184
180
|
rule.match?(path)
|
|
185
181
|
else
|
data/lib/rack/tempfile_reaper.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
|
|
|
5
8
|
# Middleware tracks and cleans Tempfiles created throughout a request (i.e. Rack::Multipart)
|
|
@@ -12,11 +15,19 @@ module Rack
|
|
|
12
15
|
|
|
13
16
|
def call(env)
|
|
14
17
|
env[RACK_TEMPFILES] ||= []
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
begin
|
|
20
|
+
_, _, body = response = @app.call(env)
|
|
21
|
+
rescue Exception
|
|
22
|
+
env[RACK_TEMPFILES]&.each(&:close!)
|
|
23
|
+
raise
|
|
18
24
|
end
|
|
19
|
-
|
|
25
|
+
|
|
26
|
+
response[2] = BodyProxy.new(body) do
|
|
27
|
+
env[RACK_TEMPFILES]&.each(&:close!)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
response
|
|
20
31
|
end
|
|
21
32
|
end
|
|
22
33
|
end
|
data/lib/rack/urlmap.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
require 'set'
|
|
4
4
|
|
|
5
|
+
require_relative 'constants'
|
|
6
|
+
|
|
5
7
|
module Rack
|
|
6
8
|
# Rack::URLMap takes a hash mapping urls or paths to apps, and
|
|
7
9
|
# dispatches accordingly. Support for HTTP/1.1 host names exists if
|
|
@@ -74,7 +76,7 @@ module Rack
|
|
|
74
76
|
return app.call(env)
|
|
75
77
|
end
|
|
76
78
|
|
|
77
|
-
[404, { CONTENT_TYPE => "text/plain", "
|
|
79
|
+
[404, { CONTENT_TYPE => "text/plain", "x-cascade" => "pass" }, ["Not Found: #{path}"]]
|
|
78
80
|
|
|
79
81
|
ensure
|
|
80
82
|
env[PATH_INFO] = path
|