rack 3.0.11 → 3.1.0

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: 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