rack 3.0.11 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28b82d44ba189d0bbbc8bde52faa4aad3e333926291cdc20f62ede702b9cf02b
4
- data.tar.gz: a40e034c12ec76cd6f9506dfac3ab12438e3c9ffb5c40a7417b0b463758dd40b
3
+ metadata.gz: f7f3809c29e2dad213f5abbdace8e3b7633072c2d3741ef484346ca07b8a9e0d
4
+ data.tar.gz: a05cea9deeb8173edc7a5e5a0647abbf0f8ff1906f74543ad6970311ab4d3a52
5
5
  SHA512:
6
- metadata.gz: 04b8e6d85dc1667f282320d629931407897342cfa2c04ec673ed7150dcb27592fd7c0624ee8d02d5f71dcd8370237b5bc425f43b5d92b6fd58aa311153b75e8f
7
- data.tar.gz: b2720568c6fbc1b192e2b0dbbff7231ca4db86f56ff9c12e70385ba7d324c6f44938426071c022789a0f8d6d73a78e383b477332d39e873569860cc059ea1158
6
+ metadata.gz: 357615f5163669e77b81660145353bf29d926ab5d92e36e958ae65063c993d9c9411b868090bc99fa6e72a8bd7e82ba5cb430343556a399e2d75acdb45000b62
7
+ data.tar.gz: 840039910ee854ec1bccff2d3078fb5b187f093480836d6023e290c49925e36e953a1a37372d619a5d3118f1d52fb7b904fed7623688c9b41ea7a7803960fcbb
data/CHANGELOG.md CHANGED
@@ -2,7 +2,41 @@
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
- ## Unreleased
5
+ ## [3.1.0] - 2024-06-11
6
+
7
+ ### SPEC Changes
8
+
9
+ - `rack.input` is now optional. ([#1997](https://github.com/rack/rack/pull/1997), [@ioquatix])
10
+ - `PATH_INFO` is now validated according to the HTTP/1.1 specification. ([#2117](https://github.com/rack/rack/pull/2117), [@ioquatix])
11
+ - `rack.protocol` is an optional environment key and response header for handling connection upgrades.
12
+
13
+ ### Added
14
+
15
+ - Introduce `module Rack::BadRequest` which is included in multipart and query parser errors. ([#2019](https://github.com/rack/rack/pull/2019), [@ioquatix])
16
+ - Add `.mjs` MIME type ([#2057](https://github.com/rack/rack/pull/2057), [@axilleas])
17
+ - `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])
18
+ - `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])
19
+
20
+ ### Changed
21
+
22
+ - `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])
23
+ - MIME type for JavaScript files (`.js`) changed from `application/javascript` to `text/javascript` ([`1bd0f15`](https://github.com/rack/rack/commit/1bd0f1597d8f4a90d47115f3e156a8ce7870c9c8))
24
+ - 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])
25
+ - `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))
26
+ - 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])
27
+
28
+ ### Removed
29
+
30
+ - Remove non-standard status codes 306, 509, & 510 and update descriptions for 413, 422, & 451. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn])
31
+ - Add fallback lookup and deprecation warning for obsolete status symbols. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn])
32
+ - Deprecate automatic cache invalidation in `Request#{GET,POST}` ([#2073](https://github.com/rack/rack/pull/2073) ([@jeremyevans])
33
+ - `Rack::Logger` is deprecated. ([#2197](https://github.com/rack/rack/pull/2197), [@ioquatix])
34
+
35
+ ### Fixed
36
+
37
+ - In `Rack::Files`, ignore the `Range` header if served file is 0 bytes. ([#2159](https://github.com/rack/rack/pull/2159), [@zarqman])
38
+
39
+ ## [3.0.11] - 2024-05-10
6
40
 
7
41
  - Backport #2062 to 3-0-stable: Do not allow `BodyProxy` to respond to `to_str`, make `to_ary` call close . ([#2062](https://github.com/rack/rack/pull/2062), [@jeremyevans](https://github.com/jeremyevans))
8
42
 
@@ -10,6 +44,18 @@ All notable changes to this project will be documented in this file. For info on
10
44
 
11
45
  - Backport #2104 to 3-0-stable: Return empty when parsing a multi-part POST with only one end delimiter. ([#2164](https://github.com/rack/rack/pull/2164), [@JoeDupuis](https://github.com/JoeDupuis))
12
46
 
47
+ ## [3.0.9.1] - 2024-02-21
48
+
49
+ ### Security
50
+
51
+ * [CVE-2024-26146] Fixed ReDoS in Accept header parsing
52
+ * [CVE-2024-25126] Fixed ReDoS in Content Type header parsing
53
+ * [CVE-2024-26141] Reject Range headers which are too large
54
+
55
+ [CVE-2024-26146]: https://github.com/advisories/GHSA-54rr-7fvw-6x8f
56
+ [CVE-2024-25126]: https://github.com/advisories/GHSA-22f2-v57c-j9cx
57
+ [CVE-2024-26141]: https://github.com/advisories/GHSA-xj5v-6v4g-jfw6
58
+
13
59
  ## [3.0.9] - 2024-01-31
14
60
 
15
61
  - Fix incorrect content-length header that was emitted when `Rack::Response#write` was used in some situations. ([#2150](https://github.com/rack/rack/pull/2150), [@mattbrictson](https://github.com/mattbrictson))
@@ -24,6 +70,8 @@ All notable changes to this project will be documented in this file. For info on
24
70
 
25
71
  ## [3.0.6.1] - 2023-03-13
26
72
 
73
+ ### Security
74
+
27
75
  - [CVE-2023-27539] Avoid ReDoS in header parsing
28
76
 
29
77
  ## [3.0.6] - 2023-03-13
@@ -34,12 +82,16 @@ All notable changes to this project will be documented in this file. For info on
34
82
 
35
83
  - Split form/query parsing into two steps. ([#2038](https://github.com/rack/rack/pull/2038), [@matthewd](https://github.com/matthewd))
36
84
 
37
- ## [3.0.4.1] - 2023-03-02
85
+ ## [3.0.4.2] - 2023-03-02
86
+
87
+ ### Security
38
88
 
39
89
  - [CVE-2023-27530] Introduce multipart_total_part_limit to limit total parts
40
90
 
41
91
  ## [3.0.4.1] - 2023-01-17
42
92
 
93
+ ### Security
94
+
43
95
  - [CVE-2022-44571] Fix ReDoS vulnerability in multipart parser
44
96
  - [CVE-2022-44570] Fix ReDoS in Rack::Utils.get_byte_ranges
45
97
  - [CVE-2022-44572] Forbid control characters in attributes (also ReDoS)
@@ -56,7 +108,7 @@ All notable changes to this project will be documented in this file. For info on
56
108
 
57
109
  - `Rack::URLMap` uses non-deprecated form of `Regexp.new`. ([#1998](https://github.com/rack/rack/pull/1998), [@weizheheng](https://github.com/weizheheng))
58
110
 
59
- ## [3.0.2] - 2022-12-05
111
+ ## [3.0.2] -2022-12-05
60
112
 
61
113
  ### Fixed
62
114
 
@@ -112,7 +164,7 @@ All notable changes to this project will be documented in this file. For info on
112
164
  - Remove deprecated Rack::Request::SCHEME_WHITELIST. ([@jeremyevans])
113
165
  - Remove internal cookie deletion using pattern matching, there are very few practical cases where it would be useful and browsers handle it correctly without us doing anything special. ([#1844](https://github.com/rack/rack/pull/1844), [@ioquatix])
114
166
  - Remove `rack.version` as it comes too late to be useful. ([#1938](https://github.com/rack/rack/pull/1938), [@ioquatix])
115
- - Extract `rackup` command, `Rack::Server`, `Rack::Handler` and related code into a separate gem. ([#1937](https://github.com/rack/rack/pull/1937), [@ioquatix])
167
+ - Extract `rackup` command, `Rack::Server`, `Rack::Handler`, `Rack::Lobster` and related code into a separate gem. ([#1937](https://github.com/rack/rack/pull/1937), [@ioquatix])
116
168
 
117
169
  ### Added
118
170
 
@@ -167,6 +219,8 @@ All notable changes to this project will be documented in this file. For info on
167
219
 
168
220
  ## [2.2.3.1] - 2022-05-27
169
221
 
222
+ ### Security
223
+
170
224
  - [CVE-2022-30123] Fix shell escaping issue in Common Logger
171
225
  - [CVE-2022-30122] Restrict parsing of broken MIME attachments
172
226
 
@@ -874,3 +928,4 @@ Items below this line are from the previously maintained HISTORY.md and NEWS.md
874
928
  [@amatsuda]: https://github.com/amatsuda "Akira Matsuda"
875
929
  [@wjordan]: https://github.com/wjordan "Will Jordan"
876
930
  [@BlakeWilliams]: https://github.com/BlakeWilliams "Blake Williams"
931
+ [@davidstosik]: https://github.com/davidstosik "David Stosik"
data/CONTRIBUTING.md CHANGED
@@ -5,6 +5,15 @@ contributors](https://github.com/rack/rack/graphs/contributors). You're
5
5
  encouraged to submit [pull requests](https://github.com/rack/rack/pulls) and
6
6
  [propose features and discuss issues](https://github.com/rack/rack/issues).
7
7
 
8
+ ## Backports
9
+
10
+ Only security patches are ideal for backporting to non-main release versions. If
11
+ you're not sure if your bug fix is backportable, you should open a discussion to
12
+ discuss it first.
13
+
14
+ The [Security Policy] documents which release versions will receive security
15
+ backports.
16
+
8
17
  ## Fork the Project
9
18
 
10
19
  Fork the [project on GitHub](https://github.com/rack/rack) and check out your
@@ -27,15 +36,6 @@ git pull upstream main
27
36
  git checkout -b my-feature-branch
28
37
  ```
29
38
 
30
- ## Bundle Install and Quick Test
31
-
32
- Ensure that you can build the project and run quick tests.
33
-
34
- ```
35
- bundle install --without extra
36
- bundle exec rake test
37
- ```
38
-
39
39
  ## Running All Tests
40
40
 
41
41
  Install all dependencies.
@@ -140,3 +140,5 @@ there!
140
140
 
141
141
  Please do know that we really appreciate and value your time and work. We love
142
142
  you, really.
143
+
144
+ [Security Policy]: SECURITY.md
data/README.md CHANGED
@@ -1,10 +1,5 @@
1
1
  # ![Rack](contrib/logo.webp)
2
2
 
3
- > **_NOTE:_** Rack v3.0.0 was recently released. Please check the [Upgrade
4
- > Guide](UPGRADE-GUIDE.md) for more details about migrating your existing
5
- > servers, middlewares and applications. For detailed information on specific
6
- > changes, check the [Change Log](CHANGELOG.md).
7
-
8
3
  Rack provides a minimal, modular, and adaptable interface for developing web
9
4
  applications in Ruby. By wrapping HTTP requests and responses in the simplest
10
5
  way possible, it unifies and distills the bridge between web servers, web
@@ -13,6 +8,32 @@ frameworks, and web application into a single method call.
13
8
  The exact details of this are described in the [Rack Specification], which all
14
9
  Rack applications should conform to.
15
10
 
11
+ ## Version support
12
+
13
+ | Version | Support |
14
+ |----------|------------------------------------|
15
+ | 3.0.x | Bug fixes and security patches. |
16
+ | 2.2.x | Security patches only. |
17
+ | <= 2.1.x | End of support. |
18
+
19
+ Please see the [Security Policy] for more information.
20
+
21
+ ## Rack 3.0
22
+
23
+ This is the latest version of Rack. It contains API improvements but also some
24
+ breaking changes. Please check the [Upgrade Guide](UPGRADE-GUIDE.md) for more
25
+ details about migrating servers, middlewares and applications designed for Rack 2
26
+ to Rack 3. For detailed information on specific changes, check the [Change Log](CHANGELOG.md).
27
+
28
+ ## Rack 2.2
29
+
30
+ This version of Rack is receiving security patches only, and effort should be
31
+ made to move to Rack 3.
32
+
33
+ Starting in Ruby 3.4 the `base64` dependency will no longer be a default gem,
34
+ and may cause a warning or error about `base64` being missing. To correct this,
35
+ add `base64` as a dependency to your project.
36
+
16
37
  ## Installation
17
38
 
18
39
  Add the rack gem to your application bundle, or follow the instructions provided
@@ -20,10 +41,10 @@ by a [supported web framework](#supported-web-frameworks):
20
41
 
21
42
  ```bash
22
43
  # Install it generally:
23
- $ gem install rack --pre
44
+ $ gem install rack
24
45
 
25
46
  # or, add it to your current application gemfile:
26
- $ bundle add rack --version 3.0.0
47
+ $ bundle add rack
27
48
  ```
28
49
 
29
50
  If you need features from `Rack::Session` or `bin/rackup` please add those gems separately.
@@ -57,7 +78,7 @@ Hello World
57
78
  Rack is supported by a wide range of servers, including:
58
79
 
59
80
  * [Agoo](https://github.com/ohler55/agoo)
60
- * [Falcon](https://github.com/socketry/falcon) **(Rack 3 Compatible)**
81
+ * [Falcon](https://github.com/socketry/falcon)
61
82
  * [Iodine](https://github.com/boazsegev/iodine)
62
83
  * [NGINX Unit](https://unit.nginx.org/)
63
84
  * [Phusion Passenger](https://www.phusionpassenger.com/) (which is mod_rack for
@@ -84,18 +105,15 @@ These frameworks and many others support the [Rack Specification]:
84
105
 
85
106
  * [Camping](https://github.com/camping/camping)
86
107
  * [Hanami](https://hanamirb.org/)
108
+ * [Ramaze](https://github.com/ramaze/ramaze)
87
109
  * [Padrino](https://padrinorb.com/)
88
- * [Roda](https://github.com/jeremyevans/roda) **(Rack 3 Compatible)**
110
+ * [Roda](https://github.com/jeremyevans/roda)
89
111
  * [Ruby on Rails](https://rubyonrails.org/)
112
+ * [Rum](https://github.com/leahneukirchen/rum)
90
113
  * [Sinatra](https://sinatrarb.com/)
91
- * [Utopia](https://github.com/socketry/utopia) **(Rack 3 Compatible)**
114
+ * [Utopia](https://github.com/socketry/utopia)
92
115
  * [WABuR](https://github.com/ohler55/wabur)
93
116
 
94
- ### Older (possibly unsupported) web frameworks
95
-
96
- * [Ramaze](http://ramaze.net/)
97
- * [Rum](https://github.com/leahneukirchen/rum)
98
-
99
117
  ## Available middleware shipped with Rack
100
118
 
101
119
  Between the server and the framework, Rack can be customized to your
@@ -307,3 +325,4 @@ would like to thank:
307
325
  Rack is released under the [MIT License](MIT-LICENSE).
308
326
 
309
327
  [Rack Specification]: SPEC.rdoc
328
+ [Security Policy]: SECURITY.md
data/SPEC.rdoc CHANGED
@@ -82,6 +82,10 @@ Rack-specific variables:
82
82
  <tt>rack.hijack</tt>:: See below, if present, an object responding
83
83
  to +call+ that is used to perform a full
84
84
  hijack.
85
+ <tt>rack.protocol</tt>:: An optional +Array+ of +String+, containing
86
+ the protocols advertised by the client in
87
+ the +upgrade+ header (HTTP/1) or the
88
+ +:protocol+ pseudo-header (HTTP/2).
85
89
  Additional environment specifications have approved to
86
90
  standardized middleware APIs. None of these are required to
87
91
  be implemented by the server.
@@ -112,7 +116,6 @@ The <tt>SERVER_PORT</tt> must be an Integer if set.
112
116
  The <tt>SERVER_NAME</tt> must be a valid authority as defined by RFC7540.
113
117
  The <tt>HTTP_HOST</tt> must be a valid authority as defined by RFC7540.
114
118
  The <tt>SERVER_PROTOCOL</tt> must match the regexp <tt>HTTP/\d(\.\d)?</tt>.
115
- If the <tt>HTTP_VERSION</tt> is present, it must equal the <tt>SERVER_PROTOCOL</tt>.
116
119
  The environment must not contain the keys
117
120
  <tt>HTTP_CONTENT_TYPE</tt> or <tt>HTTP_CONTENT_LENGTH</tt>
118
121
  (use the versions without <tt>HTTP_</tt>).
@@ -121,12 +124,17 @@ If the string values for CGI keys contain non-ASCII characters,
121
124
  they should use ASCII-8BIT encoding.
122
125
  There are the following restrictions:
123
126
  * <tt>rack.url_scheme</tt> must either be +http+ or +https+.
124
- * There must be a valid input stream in <tt>rack.input</tt>.
127
+ * There may be a valid input stream in <tt>rack.input</tt>.
125
128
  * There must be a valid error stream in <tt>rack.errors</tt>.
126
129
  * There may be a valid hijack callback in <tt>rack.hijack</tt>
130
+ * There may be a valid early hints callback in <tt>rack.early_hints</tt>
127
131
  * The <tt>REQUEST_METHOD</tt> must be a valid token.
128
132
  * The <tt>SCRIPT_NAME</tt>, if non-empty, must start with <tt>/</tt>
129
- * The <tt>PATH_INFO</tt>, if non-empty, must start with <tt>/</tt>
133
+ * The <tt>PATH_INFO</tt>, if provided, must be a valid request target.
134
+ * Only <tt>OPTIONS</tt> requests may have <tt>PATH_INFO</tt> set to <tt>*</tt> (asterisk-form).
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
+ * <tt>CONNECT</tt> and <tt>OPTIONS</tt> requests must not have <tt>PATH_INFO</tt> set to a URI (absolute-form).
137
+ * Otherwise, <tt>PATH_INFO</tt> must start with a <tt>/</tt> and must not include a fragment part starting with '#' (origin-form).
130
138
  * The <tt>CONTENT_LENGTH</tt>, if given, must consist of digits only.
131
139
  * One of <tt>SCRIPT_NAME</tt> or <tt>PATH_INFO</tt> must be
132
140
  set. <tt>PATH_INFO</tt> should be <tt>/</tt> if
@@ -144,11 +152,11 @@ exceptions. They should be invoked in reverse order of registration.
144
152
  The input stream is an IO-like object which contains the raw HTTP
145
153
  POST data.
146
154
  When applicable, its external encoding must be "ASCII-8BIT" and it
147
- must be opened in binary mode, for Ruby 1.9 compatibility.
155
+ must be opened in binary mode.
148
156
  The input stream must respond to +gets+, +each+, and +read+.
149
157
  * +gets+ must be called without arguments and return a string,
150
158
  or +nil+ on EOF.
151
- * +read+ behaves like IO#read.
159
+ * +read+ behaves like <tt>IO#read</tt>.
152
160
  Its signature is <tt>read([length, [buffer]])</tt>.
153
161
 
154
162
  If given, +length+ must be a non-negative Integer (>= 0) or +nil+,
@@ -166,8 +174,8 @@ The input stream must respond to +gets+, +each+, and +read+.
166
174
  If +buffer+ is given, then the read data will be placed
167
175
  into +buffer+ instead of a newly created String object.
168
176
  * +each+ must be called without arguments and only yield Strings.
169
- * +close+ can be called on the input stream to indicate that the
170
- any remaining input is not needed.
177
+ * +close+ can be called on the input stream to indicate that
178
+ any remaining input is not needed.
171
179
 
172
180
  === The Error Stream
173
181
 
@@ -228,6 +236,16 @@ instance is recommended.
228
236
 
229
237
  The special response header +rack.hijack+ must only be set
230
238
  if the request +env+ has a truthy +rack.hijack?+.
239
+
240
+ === Early Hints
241
+
242
+ The application or any middleware may call the <tt>rack.early_hints</tt>
243
+ with an object which would be valid as the headers of a Rack response.
244
+
245
+ If <tt>rack.early_hints</tt> is present, it must respond to #call.
246
+ If <tt>rack.early_hints</tt> is called, it must be called with
247
+ valid Rack response headers.
248
+
231
249
  == The Response
232
250
 
233
251
  === The Status
@@ -249,16 +267,26 @@ Header values must be either a String instance,
249
267
  or an Array of String instances,
250
268
  such that each String instance must not contain characters below 037.
251
269
 
252
- === The content-type
270
+ ==== The +content-type+ Header
253
271
 
254
272
  There must not be a <tt>content-type</tt> header key when the +Status+ is 1xx,
255
273
  204, or 304.
256
274
 
257
- === The content-length
275
+ ==== The +content-length+ Header
258
276
 
259
277
  There must not be a <tt>content-length</tt> header key when the
260
278
  +Status+ is 1xx, 204, or 304.
261
279
 
280
+ ==== The +rack.protocol+ Header
281
+
282
+ If the +rack.protocol+ header is present, it must be a +String+, and
283
+ must be one of the values from the +rack.protocol+ array from the
284
+ environment.
285
+
286
+ Setting this value informs the server that it should perform a
287
+ connection upgrade. In HTTP/1, this is done using the +upgrade+
288
+ header. In HTTP/2, this is done by accepting the request.
289
+
262
290
  === The Body
263
291
 
264
292
  The Body is typically an +Array+ of +String+ instances, an enumerable
@@ -301,12 +329,9 @@ the body.
301
329
 
302
330
  The Enumerable Body must respond to +each+.
303
331
  It must only be called once.
304
- It must not be called after being closed.
332
+ It must not be called after being closed,
305
333
  and must only yield String values.
306
334
 
307
- The Body itself should not be an instance of String, as this will
308
- break in Ruby 1.9.
309
-
310
335
  Middleware must not call +each+ directly on the Body.
311
336
  Instead, middleware can return a new Body that calls +each+ on the
312
337
  original Body, yielding at least once per iteration.
@@ -2,7 +2,6 @@
2
2
 
3
3
  require_relative 'abstract/handler'
4
4
  require_relative 'abstract/request'
5
- require 'base64'
6
5
 
7
6
  module Rack
8
7
  module Auth
@@ -46,7 +45,7 @@ module Rack
46
45
  end
47
46
 
48
47
  def credentials
49
- @credentials ||= Base64.decode64(params).split(':', 2)
48
+ @credentials ||= params.unpack1('m').split(':', 2)
50
49
  end
51
50
 
52
51
  def username
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rack
4
+ # Represents a 400 Bad Request error when input data fails to meet the
5
+ # requirements.
6
+ module BadRequest
7
+ end
8
+ end
data/lib/rack/builder.rb CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  require_relative 'urlmap'
4
4
 
5
+ module Rack; end
6
+ Rack::BUILDER_TOPLEVEL_BINDING = ->(builder){builder.instance_eval{binding}}
7
+
5
8
  module Rack
6
9
  # Rack::Builder provides a domain-specific language (DSL) to construct Rack
7
10
  # applications. It is primarily used to parse +config.ru+ files which
@@ -53,15 +56,15 @@ module Rack
53
56
  # Rack::Builder.parse_file('app.rb')
54
57
  # # requires app.rb, which can be anywhere in Ruby's
55
58
  # # load path. After requiring, assumes App constant
56
- # # contains Rack application
59
+ # # is a Rack application
57
60
  #
58
61
  # Rack::Builder.parse_file('./my_app.rb')
59
62
  # # requires ./my_app.rb, which should be in the
60
63
  # # process's current directory. After requiring,
61
- # # assumes MyApp constant contains Rack application
62
- def self.parse_file(path)
64
+ # # assumes MyApp constant is a Rack application
65
+ def self.parse_file(path, **options)
63
66
  if path.end_with?('.ru')
64
- return self.load_file(path)
67
+ return self.load_file(path, **options)
65
68
  else
66
69
  require path
67
70
  return Object.const_get(::File.basename(path, '.rb').split('_').map(&:capitalize).join(''))
@@ -81,7 +84,7 @@ module Rack
81
84
  # use Rack::ContentLength
82
85
  # require './app.rb'
83
86
  # run App
84
- def self.load_file(path)
87
+ def self.load_file(path, **options)
85
88
  config = ::File.read(path)
86
89
  config.slice!(/\A#{UTF_8_BOM}/) if config.encoding == Encoding::UTF_8
87
90
 
@@ -91,16 +94,18 @@ module Rack
91
94
 
92
95
  config.sub!(/^__END__\n.*\Z/m, '')
93
96
 
94
- return new_from_string(config, path)
97
+ return new_from_string(config, path, **options)
95
98
  end
96
99
 
97
100
  # Evaluate the given +builder_script+ string in the context of
98
101
  # a Rack::Builder block, returning a Rack application.
99
- def self.new_from_string(builder_script, file = "(rackup)")
102
+ def self.new_from_string(builder_script, path = "(rackup)", **options)
103
+ builder = self.new(**options)
104
+
100
105
  # We want to build a variant of TOPLEVEL_BINDING with self as a Rack::Builder instance.
101
106
  # We cannot use instance_eval(String) as that would resolve constants differently.
102
- binding, builder = TOPLEVEL_BINDING.eval('Rack::Builder.new.instance_eval { [binding, self] }')
103
- eval builder_script, binding, file
107
+ binding = BUILDER_TOPLEVEL_BINDING.call(builder)
108
+ eval(builder_script, binding, path)
104
109
 
105
110
  return builder.to_app
106
111
  end
@@ -108,16 +113,24 @@ module Rack
108
113
  # Initialize a new Rack::Builder instance. +default_app+ specifies the
109
114
  # default application if +run+ is not called later. If a block
110
115
  # is given, it is evaluated in the context of the instance.
111
- def initialize(default_app = nil, &block)
116
+ def initialize(default_app = nil, **options, &block)
112
117
  @use = []
113
118
  @map = nil
114
119
  @run = default_app
115
120
  @warmup = nil
116
121
  @freeze_app = false
122
+ @options = options
117
123
 
118
124
  instance_eval(&block) if block_given?
119
125
  end
120
126
 
127
+ # Any options provided to the Rack::Builder instance at initialization.
128
+ # These options can be server-specific. Some general options are:
129
+ #
130
+ # * +:isolation+: One of +process+, +thread+ or +fiber+. The execution
131
+ # isolation model to use.
132
+ attr :options
133
+
121
134
  # Create a new Rack::Builder instance and return the Rack application
122
135
  # generated from it.
123
136
  def self.app(default_app = nil, &block)
data/lib/rack/cascade.rb CHANGED
@@ -9,9 +9,6 @@ module Rack
9
9
  # status codes, return the last response.
10
10
 
11
11
  class Cascade
12
- # deprecated, no longer used
13
- NotFound = [404, { CONTENT_TYPE => "text/plain" }, []]
14
-
15
12
  # An array of applications to try in order.
16
13
  attr_reader :apps
17
14
 
@@ -22,7 +22,6 @@ module Rack
22
22
  ETAG = 'etag'
23
23
  EXPIRES = 'expires'
24
24
  SET_COOKIE = 'set-cookie'
25
- TRANSFER_ENCODING = 'transfer-encoding'
26
25
 
27
26
  # HTTP method verbs
28
27
  GET = 'GET'
@@ -32,6 +31,7 @@ module Rack
32
31
  DELETE = 'DELETE'
33
32
  HEAD = 'HEAD'
34
33
  OPTIONS = 'OPTIONS'
34
+ CONNECT = 'CONNECT'
35
35
  LINK = 'LINK'
36
36
  UNLINK = 'UNLINK'
37
37
  TRACE = 'TRACE'
@@ -39,6 +39,7 @@ module Rack
39
39
  # Rack environment variables
40
40
  RACK_VERSION = 'rack.version'
41
41
  RACK_TEMPFILES = 'rack.tempfiles'
42
+ RACK_EARLY_HINTS = 'rack.early_hints'
42
43
  RACK_ERRORS = 'rack.errors'
43
44
  RACK_LOGGER = 'rack.logger'
44
45
  RACK_INPUT = 'rack.input'
@@ -54,6 +55,7 @@ module Rack
54
55
  RACK_RESPONSE_FINISHED = 'rack.response_finished'
55
56
  RACK_REQUEST_FORM_INPUT = 'rack.request.form_input'
56
57
  RACK_REQUEST_FORM_HASH = 'rack.request.form_hash'
58
+ RACK_REQUEST_FORM_PAIRS = 'rack.request.form_pairs'
57
59
  RACK_REQUEST_FORM_VARS = 'rack.request.form_vars'
58
60
  RACK_REQUEST_FORM_ERROR = 'rack.request.form_error'
59
61
  RACK_REQUEST_COOKIE_HASH = 'rack.request.cookie_hash'
@@ -21,7 +21,6 @@ module Rack
21
21
 
22
22
  if !STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) &&
23
23
  !headers[CONTENT_LENGTH] &&
24
- !headers[TRANSFER_ENCODING] &&
25
24
  body.respond_to?(:to_ary)
26
25
 
27
26
  response[2] = body = body.to_ary
data/lib/rack/headers.rb CHANGED
@@ -1,9 +1,93 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  # Rack::Headers is a Hash subclass that downcases all keys. It's designed
3
5
  # to be used by rack applications that don't implement the Rack 3 SPEC
4
6
  # (by using non-lowercase response header keys), automatically handling
5
7
  # the downcasing of keys.
6
8
  class Headers < Hash
9
+ KNOWN_HEADERS = {}
10
+ %w(
11
+ Accept-CH
12
+ Accept-Patch
13
+ Accept-Ranges
14
+ Access-Control-Allow-Credentials
15
+ Access-Control-Allow-Headers
16
+ Access-Control-Allow-Methods
17
+ Access-Control-Allow-Origin
18
+ Access-Control-Expose-Headers
19
+ Access-Control-Max-Age
20
+ Age
21
+ Allow
22
+ Alt-Svc
23
+ Cache-Control
24
+ Connection
25
+ Content-Disposition
26
+ Content-Encoding
27
+ Content-Language
28
+ Content-Length
29
+ Content-Location
30
+ Content-MD5
31
+ Content-Range
32
+ Content-Security-Policy
33
+ Content-Security-Policy-Report-Only
34
+ Content-Type
35
+ Date
36
+ Delta-Base
37
+ ETag
38
+ Expect-CT
39
+ Expires
40
+ Feature-Policy
41
+ IM
42
+ Last-Modified
43
+ Link
44
+ Location
45
+ NEL
46
+ P3P
47
+ Permissions-Policy
48
+ Pragma
49
+ Preference-Applied
50
+ Proxy-Authenticate
51
+ Public-Key-Pins
52
+ Referrer-Policy
53
+ Refresh
54
+ Report-To
55
+ Retry-After
56
+ Server
57
+ Set-Cookie
58
+ Status
59
+ Strict-Transport-Security
60
+ Timing-Allow-Origin
61
+ Tk
62
+ Trailer
63
+ Transfer-Encoding
64
+ Upgrade
65
+ Vary
66
+ Via
67
+ WWW-Authenticate
68
+ Warning
69
+ X-Cascade
70
+ X-Content-Duration
71
+ X-Content-Security-Policy
72
+ X-Content-Type-Options
73
+ X-Correlation-ID
74
+ X-Correlation-Id
75
+ X-Download-Options
76
+ X-Frame-Options
77
+ X-Permitted-Cross-Domain-Policies
78
+ X-Powered-By
79
+ X-Redirect-By
80
+ X-Request-ID
81
+ X-Request-Id
82
+ X-Runtime
83
+ X-UA-Compatible
84
+ X-WebKit-CS
85
+ X-XSS-Protection
86
+ ).each do |str|
87
+ downcased = str.downcase.freeze
88
+ KNOWN_HEADERS[str] = KNOWN_HEADERS[downcased] = downcased
89
+ end
90
+
7
91
  def self.[](*items)
8
92
  if items.length % 2 != 0
9
93
  if items.length == 1 && items.first.is_a?(Hash)
@@ -28,7 +112,7 @@ module Rack
28
112
  end
29
113
 
30
114
  def []=(key, value)
31
- super(key.downcase.freeze, value)
115
+ super(KNOWN_HEADERS[key] || key.downcase.freeze, value)
32
116
  end
33
117
  alias store []=
34
118
 
@@ -148,7 +232,7 @@ module Rack
148
232
  private
149
233
 
150
234
  def downcase_key(key)
151
- key.is_a?(String) ? key.downcase : key
235
+ key.is_a?(String) ? KNOWN_HEADERS[key] || key.downcase : key
152
236
  end
153
237
  end
154
238
  end