rack 3.1.5 → 3.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c10c6fa362f15e1169822a88e4fe9edfa36b01e48ba5d338bf55e94889a097f
4
- data.tar.gz: c205f62d2490fda13b70cc5d0b3be62af5cad3efa950d5ceabc0e1980d3fef83
3
+ metadata.gz: 0d973a8acf0ebcdea8f2cb7930d3f0417cdc32a1aeddb31c5f140357b7f968e3
4
+ data.tar.gz: a480d18cd351082f259cca12af557d9245717436135d87769584f53467d08912
5
5
  SHA512:
6
- metadata.gz: 466e3dd3536d81196d86f1cc0a3fa8e833cfe96b523843160aef33267aab0e0e46501d5f163f2a72d4e3401385c43312237f67da26932b2d192c9d1bfb3dcfdc
7
- data.tar.gz: 3bcf798901aeaa5a94524864925160077f07ac26ebaa9e3ad6b080afbe45fb0a7f1f9ee89d990720aeae7d5b8dd73e2e1bf82a264323649219b59682b56cc09a
6
+ metadata.gz: 35d4ed80330dc0ac3484cbe7ba1208a27b5fc6e214873072bac0d9302bb84b06ffb93ff52abfa007298e2b305f7ffa19dde4e97afd9e58ac4ccefd8b33e62dbc
7
+ data.tar.gz: e278e7a0174d95775c006a51ef391d9bc968f7fb52bc9b4fdcb5d30859a06578946cf1a255f29349d00e0df87543d317d7590afe98fd07875d10f343603938ca
data/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference [Keep A Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
+ ## [3.1.7] - 2024-07-11
6
+
7
+ ### Fixed
8
+
9
+ - Do not remove escaped opening/closing quotes for content-disposition filenames. ([#2229](https://github.com/rack/rack/pull/2229), [@jeremyevans])
10
+ - Fix encoding setting for non-binary IO-like objects in MockRequest#env_for. ([#2227](https://github.com/rack/rack/pull/2227), [@jeremyevans])
11
+ - `Rack::Response` should not generate invalid `content-length` header. ([#2219](https://github.com/rack/rack/pull/2219), [@ioquatix])
12
+ - Allow empty PATH_INFO. ([#2214](https://github.com/rack/rack/pull/2214), [@ioquatix])
13
+
14
+ ## [3.1.6] - 2024-07-03
15
+
16
+ ### Fixed
17
+
18
+ - Fix several edge cases in `Rack::Request#parse_http_accept_header`'s implementation. ([#2226](https://github.com/rack/rack/pull/2226), [@ioquatix])
19
+
5
20
  ## [3.1.5] - 2024-07-02
6
21
 
7
22
  ### Security
@@ -19,47 +34,66 @@ All notable changes to this project will be documented in this file. For info on
19
34
  ### Fixed
20
35
 
21
36
  - Fix passing non-strings to `Rack::Utils.escape_html`. ([#2202](https://github.com/rack/rack/pull/2202), [@earlopain])
22
- - `Rack::MockResponse` gracefully handles empty cookies ([#2203](https://github.com/rack/rack/pull/2203) [@wynksaiddestroy](https://github.com/wynksaiddestroy))
37
+ - `Rack::MockResponse` gracefully handles empty cookies ([#2203](https://github.com/rack/rack/pull/2203) [@wynksaiddestroy])
23
38
 
24
39
  ## [3.1.2] - 2024-06-11
25
40
 
26
- ## Changed
27
-
28
41
  - `Rack::Response` will take in to consideration chunked encoding responses ([#2204](https://github.com/rack/rack/pull/2204), [@tenderlove])
29
42
 
30
43
  ## [3.1.1] - 2024-06-11
31
44
 
32
- - Oops, I shouldn't have shipped this
45
+ - Oops! I shouldn't have shipped that
33
46
 
34
47
  ## [3.1.0] - 2024-06-11
35
48
 
49
+ :warning: **This release includes several breaking changes.** Refer to the **Removed** section below for the list of deprecated methods that have been removed in this release.
50
+
51
+ Rack v3.1 is primarily a maintenance release that removes features deprecated in Rack v3.0. Alongside these removals, there are several improvements to the Rack SPEC, mainly focused on enhancing input and output handling. These changes aim to make Rack more efficient and align better with the requirements of server implementations and relevant HTTP specifications.
52
+
36
53
  ### SPEC Changes
37
54
 
38
- - `rack.input` is now optional. ([#1997](https://github.com/rack/rack/pull/1997), [@ioquatix])
39
- - `PATH_INFO` is now validated according to the HTTP/1.1 specification. ([#2117](https://github.com/rack/rack/pull/2117), [@ioquatix])
40
- - `rack.protocol` is an optional environment key and response header for handling connection upgrades.
55
+ - `rack.input` is now optional. ([#1997](https://github.com/rack/rack/pull/1997), [#2018](https://github.com/rack/rack/pull/2018), [@ioquatix])
56
+ - `PATH_INFO` is now validated according to the HTTP/1.1 specification. ([#2117](https://github.com/rack/rack/pull/2117), [#2181](https://github.com/rack/rack/pull/2181), [@ioquatix])
57
+ - `OPTIONS *` is now accepted. ([#2114](https://github.com/rack/rack/pull/2114), [@doriantaylor](https://github.com/doriantaylor))
58
+ - Introduce optional `rack.protocol` request and response header for handling connection upgrades. ([#1954](https://github.com/rack/rack/pull/1954), [@ioquatix])
41
59
 
42
60
  ### Added
43
61
 
62
+ - Introduce `Rack::Multipart::MissingInputError` for improved handling of missing input in `#parse_multipart`. ([#2018](https://github.com/rack/rack/pull/2018), [@ioquatix])
44
63
  - Introduce `module Rack::BadRequest` which is included in multipart and query parser errors. ([#2019](https://github.com/rack/rack/pull/2019), [@ioquatix])
45
- - Add `.mjs` MIME type ([#2057](https://github.com/rack/rack/pull/2057), [@axilleas])
46
- - `set_cookie_header` utility now supports the `partitioned` cookie attribute. This is required by Chrome in some embedded contexts. ([#2131](https://github.com/rack/rack/pull/2131), [@flavio-b])
47
- - `rack.early_hints` is now officially supported as an optional feature (already implemented by Unicorn, Puma, and Falcon). ([#1831](https://github.com/rack/rack/pull/1831), [@casperisfine, @jeremyevans])
64
+ - Add `.mjs` MIME type ([#2057](https://github.com/rack/rack/pull/2057), [@axilleas](https://github.com/axilleas))
65
+ - `set_cookie_header` utility now supports the `partitioned` cookie attribute. This is required by Chrome in some embedded contexts. ([#2131](https://github.com/rack/rack/pull/2131), [@flavio-b](https://github.com/flavio-b))
66
+ - Introduce `rack.early_hints` for sending `103 Early Hints` informational responses. ([#1831](https://github.com/rack/rack/pull/1831), [@casperisfine](https://github.com/casperisfine), [@jeremyevans])
48
67
 
49
68
  ### Changed
50
69
 
51
- - `rack.input` is now optional, and if missing, will raise an error. Use this to fail on multipart parsing a request without an input body. ([#2018](https://github.com/rack/rack/pull/2018), [@ioquatix])
52
- - MIME type for JavaScript files (`.js`) changed from `application/javascript` to `text/javascript` ([`1bd0f15`](https://github.com/rack/rack/commit/1bd0f1597d8f4a90d47115f3e156a8ce7870c9c8))
70
+ - MIME type for JavaScript files (`.js`) changed from `application/javascript` to `text/javascript` ([`1bd0f15`](https://github.com/rack/rack/commit/1bd0f1597d8f4a90d47115f3e156a8ce7870c9c8), [@ioquatix])
53
71
  - Update MIME types associated to `.ttf`, `.woff`, `.woff2` and `.otf` extensions to use mondern `font/*` types. ([#2065](https://github.com/rack/rack/pull/2065), [@davidstosik])
54
72
  - `Rack::Utils.escape_html` is now delegated to `CGI.escapeHTML`. `'` is escaped to `#39;` instead of `#x27;`. (decimal vs hexadecimal) ([#2099](https://github.com/rack/rack/pull/2099), [@JunichiIto](https://github.com/JunichiIto))
73
+ - Clarify use of `@buffered` and only update `content-length` when `Rack::Response#finish` is invoked. ([#2149](https://github.com/rack/rack/pull/2149), [@ioquatix])
74
+
75
+ ### Deprecated
76
+
77
+ - Deprecate automatic cache invalidation in `Request#{GET,POST}` ([#2073](https://github.com/rack/rack/pull/2073), [@jeremyevans])
55
78
  - Only cookie keys that are not valid according to the HTTP specifications are escaped. We are planning to deprecate this behaviour, so now a deprecation message will be emitted in this case. In the future, invalid cookie keys may not be accepted. ([#2191](https://github.com/rack/rack/pull/2191), [@ioquatix])
79
+ - `Rack::Logger` is deprecated. ([#2197](https://github.com/rack/rack/pull/2197), [@ioquatix])
80
+ - Add fallback lookup and deprecation warning for obsolete status symbols. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn](https://github.com/wtn))
81
+ - Deprecate `Rack::Request#values_at`, use `request.params.values_at` instead ([#2183](https://github.com/rack/rack/pull/2183), [@ioquatix])
56
82
 
57
83
  ### Removed
58
84
 
59
- - Remove non-standard status codes 306, 509, & 510 and update descriptions for 413, 422, & 451. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn])
60
- - Add fallback lookup and deprecation warning for obsolete status symbols. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn])
61
- - Deprecate automatic cache invalidation in `Request#{GET,POST}` ([#2073](https://github.com/rack/rack/pull/2073) ([@jeremyevans])
62
- - `Rack::Logger` is deprecated. ([#2197](https://github.com/rack/rack/pull/2197), [@ioquatix])
85
+ - Remove deprecated `Rack::Auth::Digest` with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
86
+ - Remove deprecated `Rack::Cascade::NotFound` with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
87
+ - Remove deprecated `Rack::Chunked` with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
88
+ - Remove deprecated `Rack::File`, use `Rack::Files` instead. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
89
+ - Remove deprecated `Rack::QueryParser` `key_space_limit` parameter with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
90
+ - Remove deprecated `Rack::Response#header`, use `Rack::Response#headers` instead. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
91
+ - Remove deprecated cookie methods from `Rack::Utils`: `add_cookie_to_header`, `make_delete_cookie_header`, `add_remove_cookie_to_header`. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
92
+ - Remove deprecated `Rack::Utils::HeaderHash`. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
93
+ - Remove deprecated `Rack::VERSION`, `Rack::VERSION_STRING`, `Rack.version`, use `Rack.release` instead. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix])
94
+ - Remove non-standard status codes 306, 509, & 510 and update descriptions for 413, 422, & 451. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn](https://github.com/wtn))
95
+ - Remove any dependency on `transfer-encoding: chunked`. ([#2195](https://github.com/rack/rack/pull/2195), [@ioquatix])
96
+ - Remove deprecated `Rack::Request#[]`, use `request.params[key]` instead ([#2183](https://github.com/rack/rack/pull/2183), [@ioquatix])
63
97
 
64
98
  ### Fixed
65
99
 
data/SPEC.rdoc CHANGED
@@ -130,7 +130,7 @@ There are the following restrictions:
130
130
  * There may be a valid early hints callback in <tt>rack.early_hints</tt>
131
131
  * The <tt>REQUEST_METHOD</tt> must be a valid token.
132
132
  * The <tt>SCRIPT_NAME</tt>, if non-empty, must start with <tt>/</tt>
133
- * The <tt>PATH_INFO</tt>, if provided, must be a valid request target.
133
+ * The <tt>PATH_INFO</tt>, if provided, must be a valid request target or an empty string.
134
134
  * Only <tt>OPTIONS</tt> requests may have <tt>PATH_INFO</tt> set to <tt>*</tt> (asterisk-form).
135
135
  * Only <tt>CONNECT</tt> requests may have <tt>PATH_INFO</tt> set to an authority (authority-form). Note that in HTTP/2+, the authority-form is not a valid request target.
136
136
  * <tt>CONNECT</tt> and <tt>OPTIONS</tt> requests must not have <tt>PATH_INFO</tt> set to a URI (absolute-form).
data/lib/rack/lint.rb CHANGED
@@ -361,7 +361,7 @@ module Rack
361
361
  raise LintError, "SCRIPT_NAME must start with /"
362
362
  end
363
363
 
364
- ## * The <tt>PATH_INFO</tt>, if provided, must be a valid request target.
364
+ ## * The <tt>PATH_INFO</tt>, if provided, must be a valid request target or an empty string.
365
365
  if env.include?(PATH_INFO)
366
366
  case env[PATH_INFO]
367
367
  when REQUEST_PATH_ASTERISK_FORM
@@ -381,6 +381,8 @@ module Rack
381
381
  end
382
382
  when REQUEST_PATH_ORIGIN_FORM
383
383
  ## * Otherwise, <tt>PATH_INFO</tt> must start with a <tt>/</tt> and must not include a fragment part starting with '#' (origin-form).
384
+ when ""
385
+ # Empty string is okay.
384
386
  else
385
387
  raise LintError, "PATH_INFO must start with a '/' and must not include a fragment part starting with '#' (origin-form)"
386
388
  end
@@ -139,23 +139,13 @@ module Rack
139
139
  end
140
140
  end
141
141
 
142
- input = opts[:input]
143
- if String === input
144
- rack_input = StringIO.new(input)
145
- rack_input.set_encoding(Encoding::BINARY)
146
- else
147
- if input.respond_to?(:encoding) && input.encoding != Encoding::BINARY
148
- warn "input encoding not binary", uplevel: 1
149
- if input.respond_to?(:set_encoding)
150
- input.set_encoding(Encoding::BINARY)
151
- else
152
- raise ArgumentError, "could not coerce input to binary encoding"
153
- end
154
- end
155
- rack_input = input
142
+ rack_input = opts[:input]
143
+ if String === rack_input
144
+ rack_input = StringIO.new(rack_input)
156
145
  end
157
146
 
158
147
  if rack_input
148
+ rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
159
149
  env[RACK_INPUT] = rack_input
160
150
 
161
151
  env["CONTENT_LENGTH"] ||= env[RACK_INPUT].size.to_s if env[RACK_INPUT].respond_to?(:size)
@@ -394,7 +394,6 @@ module Rack
394
394
  filename = normalize_filename(filename || '')
395
395
  filename.force_encoding(find_encoding(encoding))
396
396
  elsif filename
397
- filename = $1 if filename =~ /^"(.*)"$/
398
397
  filename = normalize_filename(filename)
399
398
  end
400
399
 
data/lib/rack/request.rb CHANGED
@@ -642,7 +642,13 @@ module Rack
642
642
  end
643
643
 
644
644
  def parse_http_accept_header(header)
645
- header.to_s.split(',').map do |part|
645
+ # It would be nice to use filter_map here, but it's Ruby 2.7+
646
+ parts = header.to_s.split(',')
647
+
648
+ parts.map! do |part|
649
+ part.strip!
650
+ next if part.empty?
651
+
646
652
  attribute, parameters = part.split(';', 2)
647
653
  attribute.strip!
648
654
  parameters&.strip!
@@ -652,6 +658,10 @@ module Rack
652
658
  end
653
659
  [attribute, quality]
654
660
  end
661
+
662
+ parts.compact!
663
+
664
+ parts
655
665
  end
656
666
 
657
667
  # Get an array of values set in the RFC 7239 `Forwarded` request header.
data/lib/rack/response.rb CHANGED
@@ -72,7 +72,8 @@ module Rack
72
72
  if body.nil?
73
73
  @body = []
74
74
  @buffered = true
75
- @length = 0
75
+ # Body is unspecified - it may be a buffered response, or it may be a HEAD response.
76
+ @length = nil
76
77
  elsif body.respond_to?(:to_str)
77
78
  @body = [body]
78
79
  @buffered = true
@@ -80,7 +81,7 @@ module Rack
80
81
  else
81
82
  @body = body
82
83
  @buffered = nil # undetermined as of yet.
83
- @length = 0
84
+ @length = nil
84
85
  end
85
86
 
86
87
  yield self if block_given?
@@ -110,14 +111,15 @@ module Rack
110
111
  close
111
112
  return [@status, @headers, []]
112
113
  else
113
- if @length && @length > 0 && !chunked?
114
- set_header CONTENT_LENGTH, @length.to_s
115
- end
116
-
117
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.
118
116
  @block = block
119
117
  return [@status, @headers, self]
120
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
121
123
  return [@status, @headers, @body]
122
124
  end
123
125
  end
@@ -135,7 +137,9 @@ module Rack
135
137
  end
136
138
  end
137
139
 
138
- # Append to body and update content-length.
140
+ # Append a chunk to the response body.
141
+ #
142
+ # Converts the response into a buffered response if it wasn't already.
139
143
  #
140
144
  # NOTE: Do not mix #write and direct #body access!
141
145
  #
@@ -336,16 +340,13 @@ module Rack
336
340
  # Turn the user supplied body into a buffered array:
337
341
  body = @body
338
342
  @body = Array.new
339
- @length = 0
343
+ @buffered = true
340
344
 
341
345
  body.each do |part|
342
346
  @writer.call(part.to_s)
343
347
  end
344
348
 
345
349
  body.close if body.respond_to?(:close)
346
-
347
- # We have converted the body into an Array:
348
- @buffered = true
349
350
  else
350
351
  # We don't know how to buffer the user-supplied body:
351
352
  @buffered = false
@@ -359,7 +360,11 @@ module Rack
359
360
  chunk = chunk.dup unless chunk.frozen?
360
361
  @body << chunk
361
362
 
362
- @length += chunk.bytesize
363
+ if @length
364
+ @length += chunk.bytesize
365
+ elsif @buffered
366
+ @length = chunk.bytesize
367
+ end
363
368
 
364
369
  return chunk
365
370
  end
data/lib/rack/version.rb CHANGED
@@ -12,7 +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
- RELEASE = "3.1.5"
15
+ RELEASE = "3.1.7"
16
16
 
17
17
  # Return the Rack release as a dotted string.
18
18
  def self.release
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.1.5
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: 2024-07-02 00:00:00.000000000 Z
11
+ date: 2024-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  - !ruby/object:Gem::Version
159
159
  version: '0'
160
160
  requirements: []
161
- rubygems_version: 3.5.11
161
+ rubygems_version: 3.5.9
162
162
  signing_key:
163
163
  specification_version: 4
164
164
  summary: A modular Ruby webserver interface.