rack 3.0.8 → 3.1.7
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 +136 -2
- data/CONTRIBUTING.md +11 -9
- data/README.md +34 -15
- data/SPEC.rdoc +38 -13
- data/lib/rack/auth/basic.rb +1 -2
- data/lib/rack/bad_request.rb +8 -0
- data/lib/rack/body_proxy.rb +18 -2
- data/lib/rack/builder.rb +23 -10
- data/lib/rack/cascade.rb +0 -3
- data/lib/rack/constants.rb +3 -0
- data/lib/rack/headers.rb +86 -2
- data/lib/rack/lint.rb +118 -34
- data/lib/rack/logger.rb +2 -1
- data/lib/rack/media_type.rb +9 -4
- data/lib/rack/mime.rb +6 -5
- data/lib/rack/mock_request.rb +10 -15
- data/lib/rack/mock_response.rb +14 -16
- data/lib/rack/multipart/parser.rb +131 -63
- data/lib/rack/multipart.rb +34 -1
- data/lib/rack/query_parser.rb +15 -68
- data/lib/rack/request.rb +40 -21
- data/lib/rack/response.rb +29 -19
- data/lib/rack/show_exceptions.rb +6 -2
- data/lib/rack/utils.rb +77 -101
- data/lib/rack/version.rb +1 -14
- data/lib/rack.rb +10 -16
- metadata +4 -10
- data/lib/rack/auth/digest/md5.rb +0 -1
- data/lib/rack/auth/digest/nonce.rb +0 -1
- data/lib/rack/auth/digest/params.rb +0 -1
- data/lib/rack/auth/digest/request.rb +0 -1
- data/lib/rack/auth/digest.rb +0 -256
- data/lib/rack/chunked.rb +0 -120
- data/lib/rack/file.rb +0 -9
data/lib/rack/response.rb
CHANGED
|
@@ -31,13 +31,6 @@ module Rack
|
|
|
31
31
|
attr_accessor :length, :status, :body
|
|
32
32
|
attr_reader :headers
|
|
33
33
|
|
|
34
|
-
# Deprecated, use headers instead.
|
|
35
|
-
def header
|
|
36
|
-
warn 'Rack::Response#header is deprecated and will be removed in Rack 3.1', uplevel: 1
|
|
37
|
-
|
|
38
|
-
headers
|
|
39
|
-
end
|
|
40
|
-
|
|
41
34
|
# Initialize the response object with the specified +body+, +status+
|
|
42
35
|
# and +headers+.
|
|
43
36
|
#
|
|
@@ -62,7 +55,7 @@ module Rack
|
|
|
62
55
|
@status = status.to_i
|
|
63
56
|
|
|
64
57
|
unless headers.is_a?(Hash)
|
|
65
|
-
|
|
58
|
+
raise ArgumentError, "Headers must be a Hash!"
|
|
66
59
|
end
|
|
67
60
|
|
|
68
61
|
@headers = Headers.new
|
|
@@ -79,7 +72,8 @@ module Rack
|
|
|
79
72
|
if body.nil?
|
|
80
73
|
@body = []
|
|
81
74
|
@buffered = true
|
|
82
|
-
|
|
75
|
+
# Body is unspecified - it may be a buffered response, or it may be a HEAD response.
|
|
76
|
+
@length = nil
|
|
83
77
|
elsif body.respond_to?(:to_str)
|
|
84
78
|
@body = [body]
|
|
85
79
|
@buffered = true
|
|
@@ -87,7 +81,7 @@ module Rack
|
|
|
87
81
|
else
|
|
88
82
|
@body = body
|
|
89
83
|
@buffered = nil # undetermined as of yet.
|
|
90
|
-
@length =
|
|
84
|
+
@length = nil
|
|
91
85
|
end
|
|
92
86
|
|
|
93
87
|
yield self if block_given?
|
|
@@ -106,7 +100,7 @@ module Rack
|
|
|
106
100
|
# The response body is an enumerable body and it is not allowed to have an entity body.
|
|
107
101
|
@body.respond_to?(:each) && STATUS_WITH_NO_ENTITY_BODY[@status]
|
|
108
102
|
end
|
|
109
|
-
|
|
103
|
+
|
|
110
104
|
# Generate a response array consistent with the requirements of the SPEC.
|
|
111
105
|
# @return [Array] a 3-tuple suitable of `[status, headers, body]`
|
|
112
106
|
# which is suitable to be returned from the middleware `#call(env)` method.
|
|
@@ -118,9 +112,14 @@ module Rack
|
|
|
118
112
|
return [@status, @headers, []]
|
|
119
113
|
else
|
|
120
114
|
if block_given?
|
|
115
|
+
# We don't add the content-length here as the user has provided a block that can #write additional chunks to the body.
|
|
121
116
|
@block = block
|
|
122
117
|
return [@status, @headers, self]
|
|
123
118
|
else
|
|
119
|
+
# If we know the length of the body, set the content-length header... except if we are chunked? which is a legacy special case where the body might already be encoded and thus the actual encoded body length and the content-length are likely to be different.
|
|
120
|
+
if @length && !chunked?
|
|
121
|
+
@headers[CONTENT_LENGTH] = @length.to_s
|
|
122
|
+
end
|
|
124
123
|
return [@status, @headers, @body]
|
|
125
124
|
end
|
|
126
125
|
end
|
|
@@ -138,7 +137,9 @@ module Rack
|
|
|
138
137
|
end
|
|
139
138
|
end
|
|
140
139
|
|
|
141
|
-
# Append to
|
|
140
|
+
# Append a chunk to the response body.
|
|
141
|
+
#
|
|
142
|
+
# Converts the response into a buffered response if it wasn't already.
|
|
142
143
|
#
|
|
143
144
|
# NOTE: Do not mix #write and direct #body access!
|
|
144
145
|
#
|
|
@@ -320,27 +321,34 @@ module Rack
|
|
|
320
321
|
|
|
321
322
|
protected
|
|
322
323
|
|
|
324
|
+
# Convert the body of this response into an internally buffered Array if possible.
|
|
325
|
+
#
|
|
326
|
+
# `@buffered` is a ternary value which indicates whether the body is buffered. It can be:
|
|
327
|
+
# * `nil` - The body has not been buffered yet.
|
|
328
|
+
# * `true` - The body is buffered as an Array instance.
|
|
329
|
+
# * `false` - The body is not buffered and cannot be buffered.
|
|
330
|
+
#
|
|
331
|
+
# @return [Boolean] whether the body is buffered as an Array instance.
|
|
323
332
|
def buffered_body!
|
|
324
333
|
if @buffered.nil?
|
|
325
334
|
if @body.is_a?(Array)
|
|
326
335
|
# The user supplied body was an array:
|
|
327
336
|
@body = @body.compact
|
|
328
|
-
@body.
|
|
329
|
-
|
|
330
|
-
end
|
|
337
|
+
@length = @body.sum{|part| part.bytesize}
|
|
338
|
+
@buffered = true
|
|
331
339
|
elsif @body.respond_to?(:each)
|
|
332
340
|
# Turn the user supplied body into a buffered array:
|
|
333
341
|
body = @body
|
|
334
342
|
@body = Array.new
|
|
343
|
+
@buffered = true
|
|
335
344
|
|
|
336
345
|
body.each do |part|
|
|
337
346
|
@writer.call(part.to_s)
|
|
338
347
|
end
|
|
339
348
|
|
|
340
349
|
body.close if body.respond_to?(:close)
|
|
341
|
-
|
|
342
|
-
@buffered = true
|
|
343
350
|
else
|
|
351
|
+
# We don't know how to buffer the user-supplied body:
|
|
344
352
|
@buffered = false
|
|
345
353
|
end
|
|
346
354
|
end
|
|
@@ -349,11 +357,13 @@ module Rack
|
|
|
349
357
|
end
|
|
350
358
|
|
|
351
359
|
def append(chunk)
|
|
360
|
+
chunk = chunk.dup unless chunk.frozen?
|
|
352
361
|
@body << chunk
|
|
353
362
|
|
|
354
|
-
|
|
363
|
+
if @length
|
|
355
364
|
@length += chunk.bytesize
|
|
356
|
-
|
|
365
|
+
elsif @buffered
|
|
366
|
+
@length = chunk.bytesize
|
|
357
367
|
end
|
|
358
368
|
|
|
359
369
|
return chunk
|
data/lib/rack/show_exceptions.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'ostruct'
|
|
4
3
|
require 'erb'
|
|
5
4
|
|
|
6
5
|
require_relative 'constants'
|
|
@@ -19,6 +18,11 @@ module Rack
|
|
|
19
18
|
class ShowExceptions
|
|
20
19
|
CONTEXT = 7
|
|
21
20
|
|
|
21
|
+
Frame = Struct.new(:filename, :lineno, :function,
|
|
22
|
+
:pre_context_lineno, :pre_context,
|
|
23
|
+
:context_line, :post_context_lineno,
|
|
24
|
+
:post_context)
|
|
25
|
+
|
|
22
26
|
def initialize(app)
|
|
23
27
|
@app = app
|
|
24
28
|
end
|
|
@@ -79,7 +83,7 @@ module Rack
|
|
|
79
83
|
# This double assignment is to prevent an "unused variable" warning.
|
|
80
84
|
# Yes, it is dumb, but I don't like Ruby yelling at me.
|
|
81
85
|
frames = frames = exception.backtrace.map { |line|
|
|
82
|
-
frame =
|
|
86
|
+
frame = Frame.new
|
|
83
87
|
if line =~ /(.*?):(\d+)(:in `(.*)')?/
|
|
84
88
|
frame.filename = $1
|
|
85
89
|
frame.lineno = $2.to_i
|
data/lib/rack/utils.rb
CHANGED
|
@@ -6,6 +6,7 @@ require 'fileutils'
|
|
|
6
6
|
require 'set'
|
|
7
7
|
require 'tempfile'
|
|
8
8
|
require 'time'
|
|
9
|
+
require 'erb'
|
|
9
10
|
|
|
10
11
|
require_relative 'query_parser'
|
|
11
12
|
require_relative 'mime'
|
|
@@ -85,15 +86,6 @@ module Rack
|
|
|
85
86
|
self.default_query_parser = self.default_query_parser.new_depth_limit(v)
|
|
86
87
|
end
|
|
87
88
|
|
|
88
|
-
def self.key_space_limit
|
|
89
|
-
warn("`Rack::Utils.key_space_limit` is deprecated as this value no longer has an effect. It will be removed in Rack 3.1", uplevel: 1)
|
|
90
|
-
65536
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def self.key_space_limit=(v)
|
|
94
|
-
warn("`Rack::Utils.key_space_limit=` is deprecated and no longer has an effect. It will be removed in Rack 3.1", uplevel: 1)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
89
|
if defined?(Process::CLOCK_MONOTONIC)
|
|
98
90
|
def clock_time
|
|
99
91
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
@@ -143,8 +135,8 @@ module Rack
|
|
|
143
135
|
end
|
|
144
136
|
|
|
145
137
|
def q_values(q_value_header)
|
|
146
|
-
q_value_header.to_s.split(
|
|
147
|
-
value, parameters = part.split(
|
|
138
|
+
q_value_header.to_s.split(',').map do |part|
|
|
139
|
+
value, parameters = part.split(';', 2).map(&:strip)
|
|
148
140
|
quality = 1.0
|
|
149
141
|
if parameters && (md = /\Aq=([\d.]+)/.match(parameters))
|
|
150
142
|
quality = md[1].to_f
|
|
@@ -157,9 +149,10 @@ module Rack
|
|
|
157
149
|
return nil unless forwarded_header
|
|
158
150
|
forwarded_header = forwarded_header.to_s.gsub("\n", ";")
|
|
159
151
|
|
|
160
|
-
forwarded_header.split(
|
|
161
|
-
field.split(
|
|
162
|
-
|
|
152
|
+
forwarded_header.split(';').each_with_object({}) do |field, values|
|
|
153
|
+
field.split(',').each do |pair|
|
|
154
|
+
pair = pair.split('=').map(&:strip).join('=')
|
|
155
|
+
return nil unless pair =~ /\A(by|for|host|proto)="?([^"]+)"?\Z/i
|
|
163
156
|
(values[$1.downcase.to_sym] ||= []) << $2
|
|
164
157
|
end
|
|
165
158
|
end
|
|
@@ -183,20 +176,16 @@ module Rack
|
|
|
183
176
|
matches&.first
|
|
184
177
|
end
|
|
185
178
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
'
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
|
198
|
-
def escape_html(string)
|
|
199
|
-
string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
|
|
179
|
+
# Introduced in ERB 4.0. ERB::Escape is an alias for ERB::Utils which
|
|
180
|
+
# doesn't get monkey-patched by rails
|
|
181
|
+
if defined?(ERB::Escape) && ERB::Escape.instance_method(:html_escape)
|
|
182
|
+
define_method(:escape_html, ERB::Escape.instance_method(:html_escape))
|
|
183
|
+
else
|
|
184
|
+
require 'cgi/escape'
|
|
185
|
+
# Escape ampersands, brackets and quotes to their HTML/XML entities.
|
|
186
|
+
def escape_html(string)
|
|
187
|
+
CGI.escapeHTML(string.to_s)
|
|
188
|
+
end
|
|
200
189
|
end
|
|
201
190
|
|
|
202
191
|
def select_best_encoding(available_encodings, accept_encoding)
|
|
@@ -251,21 +240,6 @@ module Rack
|
|
|
251
240
|
end
|
|
252
241
|
end
|
|
253
242
|
|
|
254
|
-
def add_cookie_to_header(header, key, value)
|
|
255
|
-
warn("add_cookie_to_header is deprecated and will be removed in Rack 3.1", uplevel: 1)
|
|
256
|
-
|
|
257
|
-
case header
|
|
258
|
-
when nil, ''
|
|
259
|
-
return set_cookie_header(key, value)
|
|
260
|
-
when String
|
|
261
|
-
[header, set_cookie_header(key, value)]
|
|
262
|
-
when Array
|
|
263
|
-
header + [set_cookie_header(key, value)]
|
|
264
|
-
else
|
|
265
|
-
raise ArgumentError, "Unrecognized cookie header value. Expected String, Array, or nil, got #{header.inspect}"
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
|
|
269
243
|
# :call-seq:
|
|
270
244
|
# parse_cookies(env) -> hash
|
|
271
245
|
#
|
|
@@ -279,6 +253,20 @@ module Rack
|
|
|
279
253
|
parse_cookies_header env[HTTP_COOKIE]
|
|
280
254
|
end
|
|
281
255
|
|
|
256
|
+
# A valid cookie key according to RFC2616.
|
|
257
|
+
# A <cookie-name> can be any US-ASCII characters, except control characters, spaces, or tabs. It also must not contain a separator character like the following: ( ) < > @ , ; : \ " / [ ] ? = { }.
|
|
258
|
+
VALID_COOKIE_KEY = /\A[!#$%&'*+\-\.\^_`|~0-9a-zA-Z]+\z/.freeze
|
|
259
|
+
private_constant :VALID_COOKIE_KEY
|
|
260
|
+
|
|
261
|
+
private def escape_cookie_key(key)
|
|
262
|
+
if key =~ VALID_COOKIE_KEY
|
|
263
|
+
key
|
|
264
|
+
else
|
|
265
|
+
warn "Cookie key #{key.inspect} is not valid according to RFC2616; it will be escaped. This behaviour is deprecated and will be removed in a future version of Rack.", uplevel: 2
|
|
266
|
+
escape(key)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
282
270
|
# :call-seq:
|
|
283
271
|
# set_cookie_header(key, value) -> encoded string
|
|
284
272
|
#
|
|
@@ -305,7 +293,7 @@ module Rack
|
|
|
305
293
|
def set_cookie_header(key, value)
|
|
306
294
|
case value
|
|
307
295
|
when Hash
|
|
308
|
-
key =
|
|
296
|
+
key = escape_cookie_key(key) unless value[:escape_key] == false
|
|
309
297
|
domain = "; domain=#{value[:domain]}" if value[:domain]
|
|
310
298
|
path = "; path=#{value[:path]}" if value[:path]
|
|
311
299
|
max_age = "; max-age=#{value[:max_age]}" if value[:max_age]
|
|
@@ -317,23 +305,24 @@ module Rack
|
|
|
317
305
|
when false, nil
|
|
318
306
|
nil
|
|
319
307
|
when :none, 'None', :None
|
|
320
|
-
';
|
|
308
|
+
'; samesite=none'
|
|
321
309
|
when :lax, 'Lax', :Lax
|
|
322
|
-
';
|
|
310
|
+
'; samesite=lax'
|
|
323
311
|
when true, :strict, 'Strict', :Strict
|
|
324
|
-
';
|
|
312
|
+
'; samesite=strict'
|
|
325
313
|
else
|
|
326
|
-
raise ArgumentError, "Invalid
|
|
314
|
+
raise ArgumentError, "Invalid :same_site value: #{value[:same_site].inspect}"
|
|
327
315
|
end
|
|
316
|
+
partitioned = "; partitioned" if value[:partitioned]
|
|
328
317
|
value = value[:value]
|
|
329
318
|
else
|
|
330
|
-
key =
|
|
319
|
+
key = escape_cookie_key(key)
|
|
331
320
|
end
|
|
332
321
|
|
|
333
322
|
value = [value] unless Array === value
|
|
334
323
|
|
|
335
324
|
return "#{key}=#{value.map { |v| escape v }.join('&')}#{domain}" \
|
|
336
|
-
"#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}"
|
|
325
|
+
"#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}#{partitioned}"
|
|
337
326
|
end
|
|
338
327
|
|
|
339
328
|
# :call-seq:
|
|
@@ -374,24 +363,12 @@ module Rack
|
|
|
374
363
|
set_cookie_header(key, value.merge(max_age: '0', expires: Time.at(0), value: ''))
|
|
375
364
|
end
|
|
376
365
|
|
|
377
|
-
def make_delete_cookie_header(header, key, value)
|
|
378
|
-
warn("make_delete_cookie_header is deprecated and will be removed in Rack 3.1, use delete_set_cookie_header! instead", uplevel: 1)
|
|
379
|
-
|
|
380
|
-
delete_set_cookie_header!(header, key, value)
|
|
381
|
-
end
|
|
382
|
-
|
|
383
366
|
def delete_cookie_header!(headers, key, value = {})
|
|
384
367
|
headers[SET_COOKIE] = delete_set_cookie_header!(headers[SET_COOKIE], key, value)
|
|
385
368
|
|
|
386
369
|
return nil
|
|
387
370
|
end
|
|
388
371
|
|
|
389
|
-
def add_remove_cookie_to_header(header, key, value = {})
|
|
390
|
-
warn("add_remove_cookie_to_header is deprecated and will be removed in Rack 3.1, use delete_set_cookie_header! instead", uplevel: 1)
|
|
391
|
-
|
|
392
|
-
delete_set_cookie_header!(header, key, value)
|
|
393
|
-
end
|
|
394
|
-
|
|
395
372
|
# :call-seq:
|
|
396
373
|
# delete_set_cookie_header!(header, key, value = {}) -> header value
|
|
397
374
|
#
|
|
@@ -434,6 +411,8 @@ module Rack
|
|
|
434
411
|
|
|
435
412
|
def get_byte_ranges(http_range, size)
|
|
436
413
|
# See <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35>
|
|
414
|
+
# Ignore Range when file size is 0 to avoid a 416 error.
|
|
415
|
+
return nil if size.zero?
|
|
437
416
|
return nil unless http_range && http_range =~ /bytes=([^;]+)/
|
|
438
417
|
ranges = []
|
|
439
418
|
$1.split(/,\s*/).each do |range_spec|
|
|
@@ -458,6 +437,9 @@ module Rack
|
|
|
458
437
|
end
|
|
459
438
|
ranges << (r0..r1) if r0 <= r1
|
|
460
439
|
end
|
|
440
|
+
|
|
441
|
+
return [] if ranges.map(&:size).sum > size
|
|
442
|
+
|
|
461
443
|
ranges
|
|
462
444
|
end
|
|
463
445
|
|
|
@@ -513,39 +495,12 @@ module Rack
|
|
|
513
495
|
end
|
|
514
496
|
end
|
|
515
497
|
|
|
516
|
-
# A wrapper around Headers
|
|
517
|
-
# header when set.
|
|
518
|
-
#
|
|
519
|
-
# @api private
|
|
520
|
-
class HeaderHash < Hash # :nodoc:
|
|
521
|
-
def self.[](headers)
|
|
522
|
-
warn "Rack::Utils::HeaderHash is deprecated and will be removed in Rack 3.1, switch to Rack::Headers", uplevel: 1
|
|
523
|
-
if headers.is_a?(Headers) && !headers.frozen?
|
|
524
|
-
return headers
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
new_headers = Headers.new
|
|
528
|
-
headers.each{|k,v| new_headers[k] = v}
|
|
529
|
-
new_headers
|
|
530
|
-
end
|
|
531
|
-
|
|
532
|
-
def self.new(hash = {})
|
|
533
|
-
warn "Rack::Utils::HeaderHash is deprecated and will be removed in Rack 3.1, switch to Rack::Headers", uplevel: 1
|
|
534
|
-
headers = Headers.new
|
|
535
|
-
hash.each{|k,v| headers[k] = v}
|
|
536
|
-
headers
|
|
537
|
-
end
|
|
538
|
-
|
|
539
|
-
def self.allocate
|
|
540
|
-
raise TypeError, "cannot allocate HeaderHash"
|
|
541
|
-
end
|
|
542
|
-
end
|
|
543
|
-
|
|
544
498
|
# Every standard HTTP code mapped to the appropriate message.
|
|
545
499
|
# Generated with:
|
|
546
|
-
# curl -s https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv
|
|
547
|
-
# ruby -
|
|
548
|
-
#
|
|
500
|
+
# curl -s https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv \
|
|
501
|
+
# | ruby -rcsv -e "puts CSV.parse(STDIN, headers: true) \
|
|
502
|
+
# .reject {|v| v['Description'] == 'Unassigned' or v['Description'].include? '(' } \
|
|
503
|
+
# .map {|v| %Q/#{v['Value']} => '#{v['Description']}'/ }.join(','+?\n)"
|
|
549
504
|
HTTP_STATUS_CODES = {
|
|
550
505
|
100 => 'Continue',
|
|
551
506
|
101 => 'Switching Protocols',
|
|
@@ -567,7 +522,6 @@ module Rack
|
|
|
567
522
|
303 => 'See Other',
|
|
568
523
|
304 => 'Not Modified',
|
|
569
524
|
305 => 'Use Proxy',
|
|
570
|
-
306 => '(Unused)',
|
|
571
525
|
307 => 'Temporary Redirect',
|
|
572
526
|
308 => 'Permanent Redirect',
|
|
573
527
|
400 => 'Bad Request',
|
|
@@ -583,13 +537,13 @@ module Rack
|
|
|
583
537
|
410 => 'Gone',
|
|
584
538
|
411 => 'Length Required',
|
|
585
539
|
412 => 'Precondition Failed',
|
|
586
|
-
413 => '
|
|
540
|
+
413 => 'Content Too Large',
|
|
587
541
|
414 => 'URI Too Long',
|
|
588
542
|
415 => 'Unsupported Media Type',
|
|
589
543
|
416 => 'Range Not Satisfiable',
|
|
590
544
|
417 => 'Expectation Failed',
|
|
591
545
|
421 => 'Misdirected Request',
|
|
592
|
-
422 => 'Unprocessable
|
|
546
|
+
422 => 'Unprocessable Content',
|
|
593
547
|
423 => 'Locked',
|
|
594
548
|
424 => 'Failed Dependency',
|
|
595
549
|
425 => 'Too Early',
|
|
@@ -597,7 +551,7 @@ module Rack
|
|
|
597
551
|
428 => 'Precondition Required',
|
|
598
552
|
429 => 'Too Many Requests',
|
|
599
553
|
431 => 'Request Header Fields Too Large',
|
|
600
|
-
451 => 'Unavailable
|
|
554
|
+
451 => 'Unavailable For Legal Reasons',
|
|
601
555
|
500 => 'Internal Server Error',
|
|
602
556
|
501 => 'Not Implemented',
|
|
603
557
|
502 => 'Bad Gateway',
|
|
@@ -607,8 +561,6 @@ module Rack
|
|
|
607
561
|
506 => 'Variant Also Negotiates',
|
|
608
562
|
507 => 'Insufficient Storage',
|
|
609
563
|
508 => 'Loop Detected',
|
|
610
|
-
509 => 'Bandwidth Limit Exceeded',
|
|
611
|
-
510 => 'Not Extended',
|
|
612
564
|
511 => 'Network Authentication Required'
|
|
613
565
|
}
|
|
614
566
|
|
|
@@ -616,12 +568,36 @@ module Rack
|
|
|
616
568
|
STATUS_WITH_NO_ENTITY_BODY = Hash[((100..199).to_a << 204 << 304).product([true])]
|
|
617
569
|
|
|
618
570
|
SYMBOL_TO_STATUS_CODE = Hash[*HTTP_STATUS_CODES.map { |code, message|
|
|
619
|
-
[message.downcase.gsub(/\s
|
|
571
|
+
[message.downcase.gsub(/\s|-/, '_').to_sym, code]
|
|
620
572
|
}.flatten]
|
|
621
573
|
|
|
574
|
+
OBSOLETE_SYMBOLS_TO_STATUS_CODES = {
|
|
575
|
+
payload_too_large: 413,
|
|
576
|
+
unprocessable_entity: 422,
|
|
577
|
+
bandwidth_limit_exceeded: 509,
|
|
578
|
+
not_extended: 510
|
|
579
|
+
}.freeze
|
|
580
|
+
private_constant :OBSOLETE_SYMBOLS_TO_STATUS_CODES
|
|
581
|
+
|
|
582
|
+
OBSOLETE_SYMBOL_MAPPINGS = {
|
|
583
|
+
payload_too_large: :content_too_large,
|
|
584
|
+
unprocessable_entity: :unprocessable_content
|
|
585
|
+
}.freeze
|
|
586
|
+
private_constant :OBSOLETE_SYMBOL_MAPPINGS
|
|
587
|
+
|
|
622
588
|
def status_code(status)
|
|
623
589
|
if status.is_a?(Symbol)
|
|
624
|
-
SYMBOL_TO_STATUS_CODE.fetch(status)
|
|
590
|
+
SYMBOL_TO_STATUS_CODE.fetch(status) do
|
|
591
|
+
fallback_code = OBSOLETE_SYMBOLS_TO_STATUS_CODES.fetch(status) { raise ArgumentError, "Unrecognized status code #{status.inspect}" }
|
|
592
|
+
message = "Status code #{status.inspect} is deprecated and will be removed in a future version of Rack."
|
|
593
|
+
if canonical_symbol = OBSOLETE_SYMBOL_MAPPINGS[status]
|
|
594
|
+
# message = "#{message} Please use #{canonical_symbol.inspect} instead."
|
|
595
|
+
# For now, let's not emit any warning when there is a mapping.
|
|
596
|
+
else
|
|
597
|
+
warn message, uplevel: 3
|
|
598
|
+
end
|
|
599
|
+
fallback_code
|
|
600
|
+
end
|
|
625
601
|
else
|
|
626
602
|
status.to_i
|
|
627
603
|
end
|
data/lib/rack/version.rb
CHANGED
|
@@ -12,20 +12,7 @@
|
|
|
12
12
|
# so it should be enough just to <tt>require 'rack'</tt> in your code.
|
|
13
13
|
|
|
14
14
|
module Rack
|
|
15
|
-
|
|
16
|
-
VERSION = [1, 3].freeze
|
|
17
|
-
deprecate_constant :VERSION
|
|
18
|
-
|
|
19
|
-
VERSION_STRING = "1.3".freeze
|
|
20
|
-
deprecate_constant :VERSION_STRING
|
|
21
|
-
|
|
22
|
-
# The Rack protocol version number implemented.
|
|
23
|
-
def self.version
|
|
24
|
-
warn "Rack.version is deprecated and will be removed in Rack 3.1!", uplevel: 1
|
|
25
|
-
VERSION
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
RELEASE = "3.0.8"
|
|
15
|
+
RELEASE = "3.1.7"
|
|
29
16
|
|
|
30
17
|
# Return the Rack release as a dotted string.
|
|
31
18
|
def self.release
|
data/lib/rack.rb
CHANGED
|
@@ -15,23 +15,21 @@ require_relative 'rack/version'
|
|
|
15
15
|
require_relative 'rack/constants'
|
|
16
16
|
|
|
17
17
|
module Rack
|
|
18
|
-
autoload :
|
|
18
|
+
autoload :BadRequest, "rack/bad_request"
|
|
19
19
|
autoload :BodyProxy, "rack/body_proxy"
|
|
20
|
+
autoload :Builder, "rack/builder"
|
|
20
21
|
autoload :Cascade, "rack/cascade"
|
|
21
|
-
autoload :Chunked, "rack/chunked"
|
|
22
22
|
autoload :CommonLogger, "rack/common_logger"
|
|
23
23
|
autoload :ConditionalGet, "rack/conditional_get"
|
|
24
24
|
autoload :Config, "rack/config"
|
|
25
25
|
autoload :ContentLength, "rack/content_length"
|
|
26
26
|
autoload :ContentType, "rack/content_type"
|
|
27
|
+
autoload :Deflater, "rack/deflater"
|
|
28
|
+
autoload :Directory, "rack/directory"
|
|
27
29
|
autoload :ETag, "rack/etag"
|
|
28
30
|
autoload :Events, "rack/events"
|
|
29
|
-
autoload :File, "rack/file"
|
|
30
31
|
autoload :Files, "rack/files"
|
|
31
|
-
autoload :Deflater, "rack/deflater"
|
|
32
|
-
autoload :Directory, "rack/directory"
|
|
33
32
|
autoload :ForwardRequest, "rack/recursive"
|
|
34
|
-
autoload :Handler, "rack/handler"
|
|
35
33
|
autoload :Head, "rack/head"
|
|
36
34
|
autoload :Headers, "rack/headers"
|
|
37
35
|
autoload :Lint, "rack/lint"
|
|
@@ -40,32 +38,28 @@ module Rack
|
|
|
40
38
|
autoload :MediaType, "rack/media_type"
|
|
41
39
|
autoload :MethodOverride, "rack/method_override"
|
|
42
40
|
autoload :Mime, "rack/mime"
|
|
41
|
+
autoload :MockRequest, "rack/mock_request"
|
|
42
|
+
autoload :MockResponse, "rack/mock_response"
|
|
43
|
+
autoload :Multipart, "rack/multipart"
|
|
43
44
|
autoload :NullLogger, "rack/null_logger"
|
|
44
45
|
autoload :QueryParser, "rack/query_parser"
|
|
45
46
|
autoload :Recursive, "rack/recursive"
|
|
46
47
|
autoload :Reloader, "rack/reloader"
|
|
48
|
+
autoload :Request, "rack/request"
|
|
49
|
+
autoload :Response, "rack/response"
|
|
47
50
|
autoload :RewindableInput, "rack/rewindable_input"
|
|
48
51
|
autoload :Runtime, "rack/runtime"
|
|
49
52
|
autoload :Sendfile, "rack/sendfile"
|
|
50
|
-
autoload :Server, "rack/server"
|
|
51
53
|
autoload :ShowExceptions, "rack/show_exceptions"
|
|
52
54
|
autoload :ShowStatus, "rack/show_status"
|
|
53
55
|
autoload :Static, "rack/static"
|
|
54
56
|
autoload :TempfileReaper, "rack/tempfile_reaper"
|
|
55
57
|
autoload :URLMap, "rack/urlmap"
|
|
56
58
|
autoload :Utils, "rack/utils"
|
|
57
|
-
autoload :Multipart, "rack/multipart"
|
|
58
|
-
|
|
59
|
-
autoload :MockRequest, "rack/mock_request"
|
|
60
|
-
autoload :MockResponse, "rack/mock_response"
|
|
61
|
-
|
|
62
|
-
autoload :Request, "rack/request"
|
|
63
|
-
autoload :Response, "rack/response"
|
|
64
59
|
|
|
65
60
|
module Auth
|
|
66
61
|
autoload :Basic, "rack/auth/basic"
|
|
67
|
-
autoload :AbstractRequest, "rack/auth/abstract/request"
|
|
68
62
|
autoload :AbstractHandler, "rack/auth/abstract/handler"
|
|
69
|
-
autoload :
|
|
63
|
+
autoload :AbstractRequest, "rack/auth/abstract/request"
|
|
70
64
|
end
|
|
71
65
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leah Neukirchen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-07-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|
|
@@ -89,15 +89,10 @@ files:
|
|
|
89
89
|
- lib/rack/auth/abstract/handler.rb
|
|
90
90
|
- lib/rack/auth/abstract/request.rb
|
|
91
91
|
- lib/rack/auth/basic.rb
|
|
92
|
-
- lib/rack/
|
|
93
|
-
- lib/rack/auth/digest/md5.rb
|
|
94
|
-
- lib/rack/auth/digest/nonce.rb
|
|
95
|
-
- lib/rack/auth/digest/params.rb
|
|
96
|
-
- lib/rack/auth/digest/request.rb
|
|
92
|
+
- lib/rack/bad_request.rb
|
|
97
93
|
- lib/rack/body_proxy.rb
|
|
98
94
|
- lib/rack/builder.rb
|
|
99
95
|
- lib/rack/cascade.rb
|
|
100
|
-
- lib/rack/chunked.rb
|
|
101
96
|
- lib/rack/common_logger.rb
|
|
102
97
|
- lib/rack/conditional_get.rb
|
|
103
98
|
- lib/rack/config.rb
|
|
@@ -108,7 +103,6 @@ files:
|
|
|
108
103
|
- lib/rack/directory.rb
|
|
109
104
|
- lib/rack/etag.rb
|
|
110
105
|
- lib/rack/events.rb
|
|
111
|
-
- lib/rack/file.rb
|
|
112
106
|
- lib/rack/files.rb
|
|
113
107
|
- lib/rack/head.rb
|
|
114
108
|
- lib/rack/headers.rb
|
|
@@ -164,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
164
158
|
- !ruby/object:Gem::Version
|
|
165
159
|
version: '0'
|
|
166
160
|
requirements: []
|
|
167
|
-
rubygems_version: 3.
|
|
161
|
+
rubygems_version: 3.5.9
|
|
168
162
|
signing_key:
|
|
169
163
|
specification_version: 4
|
|
170
164
|
summary: A modular Ruby webserver interface.
|
data/lib/rack/auth/digest/md5.rb
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require_relative '../digest'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require_relative '../digest'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require_relative '../digest'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
require_relative '../digest'
|