rack 3.0.11 → 3.1.6

Sign up to get free protection for your applications and to get access to all the features.
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)
@@ -184,20 +176,16 @@ module Rack
184
176
  matches&.first
185
177
  end
186
178
 
187
- ESCAPE_HTML = {
188
- "&" => "&",
189
- "<" => "&lt;",
190
- ">" => "&gt;",
191
- "'" => "&#x27;",
192
- '"' => "&quot;",
193
- "/" => "&#x2F;"
194
- }
195
-
196
- ESCAPE_HTML_PATTERN = Regexp.union(*ESCAPE_HTML.keys)
197
-
198
- # Escape ampersands, brackets and quotes to their HTML/XML entities.
199
- def escape_html(string)
200
- 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
201
189
  end
202
190
 
203
191
  def select_best_encoding(available_encodings, accept_encoding)
@@ -252,21 +240,6 @@ module Rack
252
240
  end
253
241
  end
254
242
 
255
- def add_cookie_to_header(header, key, value)
256
- warn("add_cookie_to_header is deprecated and will be removed in Rack 3.1", uplevel: 1)
257
-
258
- case header
259
- when nil, ''
260
- return set_cookie_header(key, value)
261
- when String
262
- [header, set_cookie_header(key, value)]
263
- when Array
264
- header + [set_cookie_header(key, value)]
265
- else
266
- raise ArgumentError, "Unrecognized cookie header value. Expected String, Array, or nil, got #{header.inspect}"
267
- end
268
- end
269
-
270
243
  # :call-seq:
271
244
  # parse_cookies(env) -> hash
272
245
  #
@@ -280,6 +253,20 @@ module Rack
280
253
  parse_cookies_header env[HTTP_COOKIE]
281
254
  end
282
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
+
283
270
  # :call-seq:
284
271
  # set_cookie_header(key, value) -> encoded string
285
272
  #
@@ -306,7 +293,7 @@ module Rack
306
293
  def set_cookie_header(key, value)
307
294
  case value
308
295
  when Hash
309
- key = escape(key) unless value[:escape_key] == false
296
+ key = escape_cookie_key(key) unless value[:escape_key] == false
310
297
  domain = "; domain=#{value[:domain]}" if value[:domain]
311
298
  path = "; path=#{value[:path]}" if value[:path]
312
299
  max_age = "; max-age=#{value[:max_age]}" if value[:max_age]
@@ -318,23 +305,24 @@ module Rack
318
305
  when false, nil
319
306
  nil
320
307
  when :none, 'None', :None
321
- '; SameSite=None'
308
+ '; samesite=none'
322
309
  when :lax, 'Lax', :Lax
323
- '; SameSite=Lax'
310
+ '; samesite=lax'
324
311
  when true, :strict, 'Strict', :Strict
325
- '; SameSite=Strict'
312
+ '; samesite=strict'
326
313
  else
327
- raise ArgumentError, "Invalid SameSite value: #{value[:same_site].inspect}"
314
+ raise ArgumentError, "Invalid :same_site value: #{value[:same_site].inspect}"
328
315
  end
316
+ partitioned = "; partitioned" if value[:partitioned]
329
317
  value = value[:value]
330
318
  else
331
- key = escape(key)
319
+ key = escape_cookie_key(key)
332
320
  end
333
321
 
334
322
  value = [value] unless Array === value
335
323
 
336
324
  return "#{key}=#{value.map { |v| escape v }.join('&')}#{domain}" \
337
- "#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}"
325
+ "#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}#{partitioned}"
338
326
  end
339
327
 
340
328
  # :call-seq:
@@ -375,24 +363,12 @@ module Rack
375
363
  set_cookie_header(key, value.merge(max_age: '0', expires: Time.at(0), value: ''))
376
364
  end
377
365
 
378
- def make_delete_cookie_header(header, key, value)
379
- warn("make_delete_cookie_header is deprecated and will be removed in Rack 3.1, use delete_set_cookie_header! instead", uplevel: 1)
380
-
381
- delete_set_cookie_header!(header, key, value)
382
- end
383
-
384
366
  def delete_cookie_header!(headers, key, value = {})
385
367
  headers[SET_COOKIE] = delete_set_cookie_header!(headers[SET_COOKIE], key, value)
386
368
 
387
369
  return nil
388
370
  end
389
371
 
390
- def add_remove_cookie_to_header(header, key, value = {})
391
- warn("add_remove_cookie_to_header is deprecated and will be removed in Rack 3.1, use delete_set_cookie_header! instead", uplevel: 1)
392
-
393
- delete_set_cookie_header!(header, key, value)
394
- end
395
-
396
372
  # :call-seq:
397
373
  # delete_set_cookie_header!(header, key, value = {}) -> header value
398
374
  #
@@ -435,6 +411,8 @@ module Rack
435
411
 
436
412
  def get_byte_ranges(http_range, size)
437
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?
438
416
  return nil unless http_range && http_range =~ /bytes=([^;]+)/
439
417
  ranges = []
440
418
  $1.split(/,\s*/).each do |range_spec|
@@ -517,39 +495,12 @@ module Rack
517
495
  end
518
496
  end
519
497
 
520
- # A wrapper around Headers
521
- # header when set.
522
- #
523
- # @api private
524
- class HeaderHash < Hash # :nodoc:
525
- def self.[](headers)
526
- warn "Rack::Utils::HeaderHash is deprecated and will be removed in Rack 3.1, switch to Rack::Headers", uplevel: 1
527
- if headers.is_a?(Headers) && !headers.frozen?
528
- return headers
529
- end
530
-
531
- new_headers = Headers.new
532
- headers.each{|k,v| new_headers[k] = v}
533
- new_headers
534
- end
535
-
536
- def self.new(hash = {})
537
- warn "Rack::Utils::HeaderHash is deprecated and will be removed in Rack 3.1, switch to Rack::Headers", uplevel: 1
538
- headers = Headers.new
539
- hash.each{|k,v| headers[k] = v}
540
- headers
541
- end
542
-
543
- def self.allocate
544
- raise TypeError, "cannot allocate HeaderHash"
545
- end
546
- end
547
-
548
498
  # Every standard HTTP code mapped to the appropriate message.
549
499
  # Generated with:
550
- # curl -s https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv | \
551
- # ruby -ne 'm = /^(\d{3}),(?!Unassigned|\(Unused\))([^,]+)/.match($_) and \
552
- # puts "#{m[1]} => \x27#{m[2].strip}\x27,"'
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)"
553
504
  HTTP_STATUS_CODES = {
554
505
  100 => 'Continue',
555
506
  101 => 'Switching Protocols',
@@ -571,7 +522,6 @@ module Rack
571
522
  303 => 'See Other',
572
523
  304 => 'Not Modified',
573
524
  305 => 'Use Proxy',
574
- 306 => '(Unused)',
575
525
  307 => 'Temporary Redirect',
576
526
  308 => 'Permanent Redirect',
577
527
  400 => 'Bad Request',
@@ -587,13 +537,13 @@ module Rack
587
537
  410 => 'Gone',
588
538
  411 => 'Length Required',
589
539
  412 => 'Precondition Failed',
590
- 413 => 'Payload Too Large',
540
+ 413 => 'Content Too Large',
591
541
  414 => 'URI Too Long',
592
542
  415 => 'Unsupported Media Type',
593
543
  416 => 'Range Not Satisfiable',
594
544
  417 => 'Expectation Failed',
595
545
  421 => 'Misdirected Request',
596
- 422 => 'Unprocessable Entity',
546
+ 422 => 'Unprocessable Content',
597
547
  423 => 'Locked',
598
548
  424 => 'Failed Dependency',
599
549
  425 => 'Too Early',
@@ -601,7 +551,7 @@ module Rack
601
551
  428 => 'Precondition Required',
602
552
  429 => 'Too Many Requests',
603
553
  431 => 'Request Header Fields Too Large',
604
- 451 => 'Unavailable for Legal Reasons',
554
+ 451 => 'Unavailable For Legal Reasons',
605
555
  500 => 'Internal Server Error',
606
556
  501 => 'Not Implemented',
607
557
  502 => 'Bad Gateway',
@@ -611,8 +561,6 @@ module Rack
611
561
  506 => 'Variant Also Negotiates',
612
562
  507 => 'Insufficient Storage',
613
563
  508 => 'Loop Detected',
614
- 509 => 'Bandwidth Limit Exceeded',
615
- 510 => 'Not Extended',
616
564
  511 => 'Network Authentication Required'
617
565
  }
618
566
 
@@ -620,12 +568,36 @@ module Rack
620
568
  STATUS_WITH_NO_ENTITY_BODY = Hash[((100..199).to_a << 204 << 304).product([true])]
621
569
 
622
570
  SYMBOL_TO_STATUS_CODE = Hash[*HTTP_STATUS_CODES.map { |code, message|
623
- [message.downcase.gsub(/\s|-|'/, '_').to_sym, code]
571
+ [message.downcase.gsub(/\s|-/, '_').to_sym, code]
624
572
  }.flatten]
625
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
+
626
588
  def status_code(status)
627
589
  if status.is_a?(Symbol)
628
- SYMBOL_TO_STATUS_CODE.fetch(status) { raise ArgumentError, "Unrecognized status code #{status.inspect}" }
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
629
601
  else
630
602
  status.to_i
631
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
- # The Rack protocol version number implemented.
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.11"
15
+ RELEASE = "3.1.6"
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 :Builder, "rack/builder"
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 :Digest, "rack/auth/digest"
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.0.11
4
+ version: 3.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leah Neukirchen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-09 00:00:00.000000000 Z
11
+ date: 2024-07-02 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/auth/digest.rb
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.5.3
161
+ rubygems_version: 3.5.11
168
162
  signing_key:
169
163
  specification_version: 4
170
164
  summary: A modular Ruby webserver interface.
@@ -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'