actionpack 7.2.1.1 → 8.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +86 -115
 - data/lib/action_controller/api.rb +1 -0
 - data/lib/action_controller/metal/conditional_get.rb +6 -3
 - data/lib/action_controller/metal/http_authentication.rb +6 -3
 - data/lib/action_controller/metal/instrumentation.rb +1 -2
 - data/lib/action_controller/metal/live.rb +19 -8
 - data/lib/action_controller/metal/rate_limiting.rb +13 -4
 - data/lib/action_controller/metal/renderers.rb +2 -1
 - data/lib/action_controller/metal/streaming.rb +5 -84
 - data/lib/action_controller/metal/strong_parameters.rb +274 -73
 - data/lib/action_controller/railtie.rb +1 -1
 - data/lib/action_controller/test_case.rb +4 -3
 - data/lib/action_dispatch/http/cache.rb +27 -10
 - data/lib/action_dispatch/http/content_security_policy.rb +1 -0
 - data/lib/action_dispatch/http/filter_parameters.rb +4 -9
 - data/lib/action_dispatch/http/filter_redirect.rb +2 -9
 - data/lib/action_dispatch/http/permissions_policy.rb +2 -0
 - data/lib/action_dispatch/http/request.rb +4 -2
 - data/lib/action_dispatch/journey/parser.rb +99 -196
 - data/lib/action_dispatch/journey/scanner.rb +40 -42
 - data/lib/action_dispatch/middleware/cookies.rb +4 -2
 - data/lib/action_dispatch/middleware/debug_exceptions.rb +16 -3
 - data/lib/action_dispatch/middleware/remote_ip.rb +5 -6
 - data/lib/action_dispatch/middleware/request_id.rb +2 -1
 - data/lib/action_dispatch/middleware/ssl.rb +14 -4
 - data/lib/action_dispatch/railtie.rb +2 -0
 - data/lib/action_dispatch/routing/inspector.rb +1 -1
 - data/lib/action_dispatch/routing/mapper.rb +26 -17
 - data/lib/action_dispatch/routing/route_set.rb +18 -6
 - data/lib/action_dispatch/system_testing/browser.rb +12 -21
 - data/lib/action_pack/gem_version.rb +4 -4
 - metadata +12 -34
 - data/lib/action_dispatch/journey/parser.y +0 -50
 - data/lib/action_dispatch/journey/parser_extras.rb +0 -33
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 4392b60cf6c4af7ed943daf2c4e438440689b8f869a859510b1e0e5808204cf2
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: ee9993b25b397af527f1730dc439a0425a81d4b03afb148e310dac8862003261
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 2063ad6ca3243b066226af6a1d1ad616d808c48a18f80df374d02b064ad4839a971e4eff804321621d910111829b0c1130b5a05f5a44afabb380ec9f7d5985b7
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: f3f1e1ce84c47654f69cf3f3ada2afa48e412dac1b7a5abd10c4d0fc34b66b7574f2454410c323cfa26a000005da585815db8a27dc3f1e9c2a71a504b0f3021d
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,164 +1,135 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            ## Rails  
     | 
| 
      
 1 
     | 
    
         
            +
            ## Rails 8.0.0.beta1 (September 26, 2024) ##
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            *    
     | 
| 
      
 3 
     | 
    
         
            +
            *   Fix non-GET requests not updating cookies in `ActionController::TestCase`.
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
                 
     | 
| 
      
 5 
     | 
    
         
            +
                *Jon Moss*, *Hartley McGuire*
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
            *    
     | 
| 
      
 7 
     | 
    
         
            +
            *   Update `ActionController::Live` to use a thread-pool to reuse threads across requests.
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
      
 9 
     | 
    
         
            +
                *Adam Renberg Tamm*
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
            *   Introduce safer, more explicit params handling method with `params#expect` such that
         
     | 
| 
      
 12 
     | 
    
         
            +
                `params.expect(table: [ :attr ])` replaces `params.require(:table).permit(:attr)`
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
            ## Rails 7.2.0 (August 09, 2024) ##
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
            *   Allow bots to ignore `allow_browser`.
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                *Matthew Nguyen*
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            *   Include the HTTP Permissions-Policy on non-HTML Content-Types
         
     | 
| 
       25 
     | 
    
         
            -
                [CVE-2024-28103]
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                *Aaron Patterson*, *Zack Deveau*
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            *   Fix `Mime::Type.parse` handling type parameters for HTTP Accept headers.
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                *Taylor Chaparro*
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            *   Fix the error page that is displayed when a view template is missing to account for nested controller paths in the
         
     | 
| 
       34 
     | 
    
         
            -
                suggested correct location for the missing template.
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                *Joshua Young*
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
            *   Add `save_and_open_page` helper to `IntegrationTest`.
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
                `save_and_open_page` is a helpful helper to keep a short feedback loop when working on system tests.
         
     | 
| 
       41 
     | 
    
         
            -
                A similar helper with matching signature has been added to integration tests.
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                *Joé Dupuis*
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
            *   Fix a regression in 7.1.3 passing a `to:` option without a controller when the controller is already defined by a scope.
         
     | 
| 
      
 14 
     | 
    
         
            +
                Ensures params are filtered with consideration for the expected
         
     | 
| 
      
 15 
     | 
    
         
            +
                types of values, improving handling of params and avoiding ignorable
         
     | 
| 
      
 16 
     | 
    
         
            +
                errors caused by params tampering.
         
     | 
| 
       46 
17 
     | 
    
         | 
| 
       47 
18 
     | 
    
         
             
                ```ruby
         
     | 
| 
       48 
     | 
    
         
            -
                 
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
                # If the url is altered to ?person=hacked
         
     | 
| 
      
 20 
     | 
    
         
            +
                # Before
         
     | 
| 
      
 21 
     | 
    
         
            +
                params.require(:person).permit(:name, :age, pets: [:name])
         
     | 
| 
      
 22 
     | 
    
         
            +
                # raises NoMethodError, causing a 500 and potential error reporting
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                # After
         
     | 
| 
      
 25 
     | 
    
         
            +
                params.expect(person: [ :name, :age, pets: [[:name]] ])
         
     | 
| 
      
 26 
     | 
    
         
            +
                # raises ActionController::ParameterMissing, correctly returning a 400 error
         
     | 
| 
       53 
27 
     | 
    
         
             
                ```
         
     | 
| 
       54 
28 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                 
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
                 
     | 
| 
      
 29 
     | 
    
         
            +
                You may also notice the new double array `[[:name]]`. In order to
         
     | 
| 
      
 30 
     | 
    
         
            +
                declare when a param is expected to be an array of parameter hashes,
         
     | 
| 
      
 31 
     | 
    
         
            +
                this new double array syntax is used to explicitly declare an array.
         
     | 
| 
      
 32 
     | 
    
         
            +
                `expect` requires you to declare expected arrays in this way, and will
         
     | 
| 
      
 33 
     | 
    
         
            +
                ignore arrays that are passed when, for example, `pet: [:name]` is used.
         
     | 
| 
       60 
34 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
                In order to preserve compatibility, `permit` does not adopt the new
         
     | 
| 
      
 36 
     | 
    
         
            +
                double array syntax and is therefore more permissive about unexpected
         
     | 
| 
      
 37 
     | 
    
         
            +
                types. Using `expect` everywhere is recommended.
         
     | 
| 
       62 
38 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                 
     | 
| 
      
 39 
     | 
    
         
            +
                We suggest replacing `params.require(:person).permit(:name, :age)`
         
     | 
| 
      
 40 
     | 
    
         
            +
                with the direct replacement `params.expect(person: [:name, :age])`
         
     | 
| 
      
 41 
     | 
    
         
            +
                to prevent external users from manipulating params to trigger 500
         
     | 
| 
      
 42 
     | 
    
         
            +
                errors. A 400 error will be returned instead, using public/400.html
         
     | 
| 
       64 
43 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                 
     | 
| 
      
 44 
     | 
    
         
            +
                Usage of `params.require(:id)` should likewise be replaced with
         
     | 
| 
      
 45 
     | 
    
         
            +
                `params.expect(:id)` which is designed to ensure that `params[:id]`
         
     | 
| 
      
 46 
     | 
    
         
            +
                is a scalar and not an array or hash, also requiring the param.
         
     | 
| 
       68 
47 
     | 
    
         | 
| 
       69 
48 
     | 
    
         
             
                ```ruby
         
     | 
| 
       70 
     | 
    
         
            -
                 
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                  allow_browser versions: :modern
         
     | 
| 
       73 
     | 
    
         
            -
                end
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                class ApplicationController < ActionController::Base
         
     | 
| 
       76 
     | 
    
         
            -
                  # All versions of Chrome and Opera will be allowed, but no versions of "internet explorer" (ie). Safari needs to be 16.4+ and Firefox 121+.
         
     | 
| 
       77 
     | 
    
         
            -
                  allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
         
     | 
| 
       78 
     | 
    
         
            -
                end
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
                class MessagesController < ApplicationController
         
     | 
| 
       81 
     | 
    
         
            -
                  # In addition to the browsers blocked by ApplicationController, also block Opera below 104 and Chrome below 119 for the show action.
         
     | 
| 
       82 
     | 
    
         
            -
                  allow_browser versions: { opera: 104, chrome: 119 }, only: :show
         
     | 
| 
       83 
     | 
    
         
            -
                end
         
     | 
| 
       84 
     | 
    
         
            -
                ```
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                *DHH*
         
     | 
| 
      
 49 
     | 
    
         
            +
                # Before
         
     | 
| 
      
 50 
     | 
    
         
            +
                User.find(params.require(:id)) # allows an array, altering behavior
         
     | 
| 
       87 
51 
     | 
    
         | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
                ```ruby
         
     | 
| 
       91 
     | 
    
         
            -
                class SessionsController < ApplicationController
         
     | 
| 
       92 
     | 
    
         
            -
                  rate_limit to: 10, within: 3.minutes, only: :create
         
     | 
| 
       93 
     | 
    
         
            -
                end
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
                class SignupsController < ApplicationController
         
     | 
| 
       96 
     | 
    
         
            -
                  rate_limit to: 1000, within: 10.seconds,
         
     | 
| 
       97 
     | 
    
         
            -
                    by: -> { request.domain }, with: -> { redirect_to busy_controller_url, alert: "Too many signups!" }, only: :new
         
     | 
| 
       98 
     | 
    
         
            -
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
                # After
         
     | 
| 
      
 53 
     | 
    
         
            +
                User.find(params.expect(:id)) # expect only returns non-blank permitted scalars (excludes Hash, Array, nil, "", etc)
         
     | 
| 
       99 
54 
     | 
    
         
             
                ```
         
     | 
| 
       100 
55 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
                * 
     | 
| 
      
 56 
     | 
    
         
            +
                *Martin Emde*
         
     | 
| 
       102 
57 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
            *    
     | 
| 
      
 58 
     | 
    
         
            +
            *   System Testing: Disable Chrome's search engine choice by default in system tests.
         
     | 
| 
       104 
59 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
                * 
     | 
| 
      
 60 
     | 
    
         
            +
                *glaszig*
         
     | 
| 
       106 
61 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
            *    
     | 
| 
      
 62 
     | 
    
         
            +
            *   Fix `Request#raw_post` raising `NoMethodError` when `rack.input` is `nil`.
         
     | 
| 
       108 
63 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
                 
     | 
| 
      
 64 
     | 
    
         
            +
                *Hartley McGuire*
         
     | 
| 
       110 
65 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
      
 66 
     | 
    
         
            +
            *   Remove `racc` dependency by manually writing `ActionDispatch::Journey::Scanner`.
         
     | 
| 
       112 
67 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
            * 
     | 
| 
      
 68 
     | 
    
         
            +
                *Gannon McGibbon*
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            *   Speed up `ActionDispatch::Routing::Mapper::Scope#[]` by merging frame hashes.
         
     | 
| 
       114 
71 
     | 
    
         | 
| 
       115 
72 
     | 
    
         
             
                *Gannon McGibbon*
         
     | 
| 
       116 
73 
     | 
    
         | 
| 
       117 
     | 
    
         
            -
            *    
     | 
| 
      
 74 
     | 
    
         
            +
            *   Allow bots to ignore `allow_browser`.
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                *Matthew Nguyen*
         
     | 
| 
       118 
77 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 78 
     | 
    
         
            +
            *   Deprecate drawing routes with multiple paths to make routing faster.
         
     | 
| 
      
 79 
     | 
    
         
            +
                You may use `with_options` or a loop to make drawing multiple paths easier.
         
     | 
| 
       120 
80 
     | 
    
         | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
                ```ruby
         
     | 
| 
      
 82 
     | 
    
         
            +
                # Before
         
     | 
| 
      
 83 
     | 
    
         
            +
                get "/users", "/other_path", to: "users#index"
         
     | 
| 
       122 
84 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
                 
     | 
| 
      
 85 
     | 
    
         
            +
                # After
         
     | 
| 
      
 86 
     | 
    
         
            +
                get "/users", to: "users#index"
         
     | 
| 
      
 87 
     | 
    
         
            +
                get "/other_path", to: "users#index"
         
     | 
| 
      
 88 
     | 
    
         
            +
                ```
         
     | 
| 
       124 
89 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
            * 
     | 
| 
      
 90 
     | 
    
         
            +
                *Gannon McGibbon*
         
     | 
| 
       126 
91 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
      
 92 
     | 
    
         
            +
            *   Make `http_cache_forever` use `immutable: true`
         
     | 
| 
       128 
93 
     | 
    
         | 
| 
       129 
     | 
    
         
            -
            * 
     | 
| 
      
 94 
     | 
    
         
            +
                *Nate Matykiewicz*
         
     | 
| 
       130 
95 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
      
 96 
     | 
    
         
            +
            *   Add `config.action_dispatch.strict_freshness`.
         
     | 
| 
       132 
97 
     | 
    
         | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
      
 98 
     | 
    
         
            +
                When set to `true`, the `ETag` header takes precedence over the `Last-Modified` header when both are present,
         
     | 
| 
      
 99 
     | 
    
         
            +
                as specified by RFC 7232, Section 6.
         
     | 
| 
       134 
100 
     | 
    
         | 
| 
       135 
     | 
    
         
            -
                 
     | 
| 
      
 101 
     | 
    
         
            +
                Defaults to `false` to maintain compatibility with previous versions of Rails, but is enabled as part of
         
     | 
| 
      
 102 
     | 
    
         
            +
                Rails 8.0 defaults.
         
     | 
| 
       136 
103 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
            * 
     | 
| 
      
 104 
     | 
    
         
            +
                *heka1024*
         
     | 
| 
       138 
105 
     | 
    
         | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
      
 106 
     | 
    
         
            +
            *   Support `immutable` directive in Cache-Control
         
     | 
| 
       140 
107 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                 
     | 
| 
      
 108 
     | 
    
         
            +
                ```ruby
         
     | 
| 
      
 109 
     | 
    
         
            +
                expires_in 1.minute, public: true, immutable: true
         
     | 
| 
      
 110 
     | 
    
         
            +
                # Cache-Control: public, max-age=60, immutable
         
     | 
| 
      
 111 
     | 
    
         
            +
                ```
         
     | 
| 
       143 
112 
     | 
    
         | 
| 
       144 
     | 
    
         
            -
                * 
     | 
| 
      
 113 
     | 
    
         
            +
                *heka1024*
         
     | 
| 
       145 
114 
     | 
    
         | 
| 
       146 
     | 
    
         
            -
            *   Add ` 
     | 
| 
      
 115 
     | 
    
         
            +
            *   Add `:wasm_unsafe_eval` mapping for `content_security_policy`
         
     | 
| 
       147 
116 
     | 
    
         | 
| 
       148 
     | 
    
         
            -
                 
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
      
 117 
     | 
    
         
            +
                ```ruby
         
     | 
| 
      
 118 
     | 
    
         
            +
                # Before
         
     | 
| 
      
 119 
     | 
    
         
            +
                policy.script_src "'wasm-unsafe-eval'"
         
     | 
| 
       150 
120 
     | 
    
         | 
| 
       151 
     | 
    
         
            -
                 
     | 
| 
      
 121 
     | 
    
         
            +
                # After
         
     | 
| 
      
 122 
     | 
    
         
            +
                policy.script_src :wasm_unsafe_eval
         
     | 
| 
      
 123 
     | 
    
         
            +
                ```
         
     | 
| 
       152 
124 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
            * 
     | 
| 
      
 125 
     | 
    
         
            +
                *Joe Haig*
         
     | 
| 
       154 
126 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
                The result would be like this:
         
     | 
| 
      
 127 
     | 
    
         
            +
            *   Add `display_capture` and `keyboard_map` in `permissions_policy`
         
     | 
| 
       157 
128 
     | 
    
         | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
      
 129 
     | 
    
         
            +
                *Cyril Blaecke*
         
     | 
| 
       159 
130 
     | 
    
         | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
      
 131 
     | 
    
         
            +
            *   Add `connect` route helper.
         
     | 
| 
       161 
132 
     | 
    
         | 
| 
       162 
     | 
    
         
            -
                * 
     | 
| 
      
 133 
     | 
    
         
            +
                *Samuel Williams*
         
     | 
| 
       163 
134 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
            Please check [7- 
     | 
| 
      
 135 
     | 
    
         
            +
            Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/actionpack/CHANGELOG.md) for previous changes.
         
     | 
| 
         @@ -76,8 +76,7 @@ module ActionController 
     | 
|
| 
       76 
76 
     | 
    
         
             
                # `:cache_control`
         
     | 
| 
       77 
77 
     | 
    
         
             
                # :   When given, will overwrite an existing `Cache-Control` header. For a list
         
     | 
| 
       78 
78 
     | 
    
         
             
                #     of `Cache-Control` directives, see the [article on
         
     | 
| 
       79 
     | 
    
         
            -
                #     MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache- 
     | 
| 
       80 
     | 
    
         
            -
                #     ol).
         
     | 
| 
      
 79 
     | 
    
         
            +
                #     MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control).
         
     | 
| 
       81 
80 
     | 
    
         
             
                #
         
     | 
| 
       82 
81 
     | 
    
         
             
                # `:template`
         
     | 
| 
       83 
82 
     | 
    
         
             
                # :   By default, the template digest for the current controller/action is
         
     | 
| 
         @@ -260,6 +259,9 @@ module ActionController 
     | 
|
| 
       260 
259 
     | 
    
         
             
                # `:stale_if_error`
         
     | 
| 
       261 
260 
     | 
    
         
             
                # :   Sets the value of the `stale-if-error` directive.
         
     | 
| 
       262 
261 
     | 
    
         
             
                #
         
     | 
| 
      
 262 
     | 
    
         
            +
                # `:immutable`
         
     | 
| 
      
 263 
     | 
    
         
            +
                # :   If true, adds the `immutable` directive.
         
     | 
| 
      
 264 
     | 
    
         
            +
                #
         
     | 
| 
       263 
265 
     | 
    
         
             
                #
         
     | 
| 
       264 
266 
     | 
    
         
             
                # Any additional key-value pairs are concatenated as directives. For a list of
         
     | 
| 
       265 
267 
     | 
    
         
             
                # supported `Cache-Control` directives, see the [article on
         
     | 
| 
         @@ -293,6 +295,7 @@ module ActionController 
     | 
|
| 
       293 
295 
     | 
    
         
             
                    must_revalidate: options.delete(:must_revalidate),
         
     | 
| 
       294 
296 
     | 
    
         
             
                    stale_while_revalidate: options.delete(:stale_while_revalidate),
         
     | 
| 
       295 
297 
     | 
    
         
             
                    stale_if_error: options.delete(:stale_if_error),
         
     | 
| 
      
 298 
     | 
    
         
            +
                    immutable: options.delete(:immutable),
         
     | 
| 
       296 
299 
     | 
    
         
             
                  )
         
     | 
| 
       297 
300 
     | 
    
         
             
                  options.delete(:private)
         
     | 
| 
       298 
301 
     | 
    
         | 
| 
         @@ -316,7 +319,7 @@ module ActionController 
     | 
|
| 
       316 
319 
     | 
    
         
             
                #     user's web browser. To allow proxies to cache the response, set `true` to
         
     | 
| 
       317 
320 
     | 
    
         
             
                #     indicate that they can serve the cached response to all users.
         
     | 
| 
       318 
321 
     | 
    
         
             
                def http_cache_forever(public: false)
         
     | 
| 
       319 
     | 
    
         
            -
                  expires_in 100.years, public: public
         
     | 
| 
      
 322 
     | 
    
         
            +
                  expires_in 100.years, public: public, immutable: true
         
     | 
| 
       320 
323 
     | 
    
         | 
| 
       321 
324 
     | 
    
         
             
                  yield if stale?(etag: request.fullpath,
         
     | 
| 
       322 
325 
     | 
    
         
             
                                  last_modified: Time.new(2011, 1, 1).utc,
         
     | 
| 
         @@ -211,7 +211,7 @@ module ActionController 
     | 
|
| 
       211 
211 
     | 
    
         
             
                    end
         
     | 
| 
       212 
212 
     | 
    
         
             
                  end
         
     | 
| 
       213 
213 
     | 
    
         | 
| 
       214 
     | 
    
         
            -
                  # Returns  
     | 
| 
      
 214 
     | 
    
         
            +
                  # Returns true on a valid response, false otherwise.
         
     | 
| 
       215 
215 
     | 
    
         
             
                  def authenticate(request, realm, &password_procedure)
         
     | 
| 
       216 
216 
     | 
    
         
             
                    request.authorization && validate_digest_response(request, realm, &password_procedure)
         
     | 
| 
       217 
217 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -431,7 +431,7 @@ module ActionController 
     | 
|
| 
       431 
431 
     | 
    
         
             
                  module ControllerMethods
         
     | 
| 
       432 
432 
     | 
    
         
             
                    # Authenticate using an HTTP Bearer token, or otherwise render an HTTP header
         
     | 
| 
       433 
433 
     | 
    
         
             
                    # requesting the client to send a Bearer token. For the authentication to be
         
     | 
| 
       434 
     | 
    
         
            -
                    # considered successful, `login_procedure`  
     | 
| 
      
 434 
     | 
    
         
            +
                    # considered successful, `login_procedure` must not return a false value.
         
     | 
| 
       435 
435 
     | 
    
         
             
                    # Typically, the authenticated user is returned.
         
     | 
| 
       436 
436 
     | 
    
         
             
                    #
         
     | 
| 
       437 
437 
     | 
    
         
             
                    # See ActionController::HttpAuthentication::Token for example usage.
         
     | 
| 
         @@ -513,11 +513,14 @@ module ActionController 
     | 
|
| 
       513 
513 
     | 
    
         
             
                    array_params.each { |param| (param[1] || +"").gsub! %r/^"|"$/, "" }
         
     | 
| 
       514 
514 
     | 
    
         
             
                  end
         
     | 
| 
       515 
515 
     | 
    
         | 
| 
      
 516 
     | 
    
         
            +
                  WHITESPACED_AUTHN_PAIR_DELIMITERS = /\s*#{AUTHN_PAIR_DELIMITERS}\s*/
         
     | 
| 
      
 517 
     | 
    
         
            +
                  private_constant :WHITESPACED_AUTHN_PAIR_DELIMITERS
         
     | 
| 
      
 518 
     | 
    
         
            +
             
     | 
| 
       516 
519 
     | 
    
         
             
                  # This method takes an authorization body and splits up the key-value pairs by
         
     | 
| 
       517 
520 
     | 
    
         
             
                  # the standardized `:`, `;`, or `\t` delimiters defined in
         
     | 
| 
       518 
521 
     | 
    
         
             
                  # `AUTHN_PAIR_DELIMITERS`.
         
     | 
| 
       519 
522 
     | 
    
         
             
                  def raw_params(auth)
         
     | 
| 
       520 
     | 
    
         
            -
                    _raw_params = auth.sub(TOKEN_REGEX, "").split( 
     | 
| 
      
 523 
     | 
    
         
            +
                    _raw_params = auth.sub(TOKEN_REGEX, "").split(WHITESPACED_AUTHN_PAIR_DELIMITERS)
         
     | 
| 
       521 
524 
     | 
    
         
             
                    _raw_params.reject!(&:empty?)
         
     | 
| 
       522 
525 
     | 
    
         | 
| 
       523 
526 
     | 
    
         
             
                    if !_raw_params.first&.start_with?(TOKEN_KEY)
         
     | 
| 
         @@ -2,7 +2,6 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # :markup: markdown
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            require "benchmark"
         
     | 
| 
       6 
5 
     | 
    
         
             
            require "abstract_controller/logger"
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
7 
     | 
    
         
             
            module ActionController
         
     | 
| 
         @@ -29,7 +28,7 @@ module ActionController 
     | 
|
| 
       29 
28 
     | 
    
         
             
                def render(*)
         
     | 
| 
       30 
29 
     | 
    
         
             
                  render_output = nil
         
     | 
| 
       31 
30 
     | 
    
         
             
                  self.view_runtime = cleanup_view_runtime do
         
     | 
| 
       32 
     | 
    
         
            -
                    Benchmark. 
     | 
| 
      
 31 
     | 
    
         
            +
                    ActiveSupport::Benchmark.realtime(:float_millisecond) { render_output = super }
         
     | 
| 
       33 
32 
     | 
    
         
             
                  end
         
     | 
| 
       34 
33 
     | 
    
         
             
                  render_output
         
     | 
| 
       35 
34 
     | 
    
         
             
                end
         
     | 
| 
         @@ -77,12 +77,15 @@ module ActionController 
     | 
|
| 
       77 
77 
     | 
    
         
             
                # Writing an object will convert it into standard SSE format with whatever
         
     | 
| 
       78 
78 
     | 
    
         
             
                # options you have configured. You may choose to set the following options:
         
     | 
| 
       79 
79 
     | 
    
         
             
                #
         
     | 
| 
       80 
     | 
    
         
            -
                # 
     | 
| 
       81 
     | 
    
         
            -
                # 
     | 
| 
       82 
     | 
    
         
            -
                # 
     | 
| 
       83 
     | 
    
         
            -
                # 
     | 
| 
       84 
     | 
    
         
            -
                # 
     | 
| 
       85 
     | 
    
         
            -
                # 
     | 
| 
      
 80 
     | 
    
         
            +
                # `:event`
         
     | 
| 
      
 81 
     | 
    
         
            +
                # :   If specified, an event with this name will be dispatched on the browser.
         
     | 
| 
      
 82 
     | 
    
         
            +
                #
         
     | 
| 
      
 83 
     | 
    
         
            +
                # `:retry`
         
     | 
| 
      
 84 
     | 
    
         
            +
                # :   The reconnection time in milliseconds used when attempting to send the event.
         
     | 
| 
      
 85 
     | 
    
         
            +
                #
         
     | 
| 
      
 86 
     | 
    
         
            +
                # `:id`
         
     | 
| 
      
 87 
     | 
    
         
            +
                # :   If the connection dies while sending an SSE to the browser, then the
         
     | 
| 
      
 88 
     | 
    
         
            +
                #     server will receive a `Last-Event-ID` header with value equal to `id`.
         
     | 
| 
       86 
89 
     | 
    
         
             
                #
         
     | 
| 
       87 
90 
     | 
    
         
             
                # After setting an option in the constructor of the SSE object, all future SSEs
         
     | 
| 
       88 
91 
     | 
    
         
             
                # sent across the stream will use those options unless overridden.
         
     | 
| 
         @@ -304,6 +307,10 @@ module ActionController 
     | 
|
| 
       304 
307 
     | 
    
         
             
                          error = e
         
     | 
| 
       305 
308 
     | 
    
         
             
                        end
         
     | 
| 
       306 
309 
     | 
    
         
             
                      ensure
         
     | 
| 
      
 310 
     | 
    
         
            +
                        # Ensure we clean up any thread locals we copied so that the thread can reused.
         
     | 
| 
      
 311 
     | 
    
         
            +
                        ActiveSupport::IsolatedExecutionState.clear
         
     | 
| 
      
 312 
     | 
    
         
            +
                        locals.each { |k, _| t2[k] = nil }
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
       307 
314 
     | 
    
         
             
                        @_response.commit!
         
     | 
| 
       308 
315 
     | 
    
         
             
                      end
         
     | 
| 
       309 
316 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -368,11 +375,15 @@ module ActionController 
     | 
|
| 
       368 
375 
     | 
    
         
             
                  # data from the response bodies. Nobody should call this method except in Rails
         
     | 
| 
       369 
376 
     | 
    
         
             
                  # internals. Seriously!
         
     | 
| 
       370 
377 
     | 
    
         
             
                  def new_controller_thread # :nodoc:
         
     | 
| 
       371 
     | 
    
         
            -
                     
     | 
| 
      
 378 
     | 
    
         
            +
                    ActionController::Live.live_thread_pool_executor.post do
         
     | 
| 
       372 
379 
     | 
    
         
             
                      t2 = Thread.current
         
     | 
| 
       373 
380 
     | 
    
         
             
                      t2.abort_on_exception = true
         
     | 
| 
       374 
381 
     | 
    
         
             
                      yield
         
     | 
| 
       375 
     | 
    
         
            -
                     
     | 
| 
      
 382 
     | 
    
         
            +
                    end
         
     | 
| 
      
 383 
     | 
    
         
            +
                  end
         
     | 
| 
      
 384 
     | 
    
         
            +
             
     | 
| 
      
 385 
     | 
    
         
            +
                  def self.live_thread_pool_executor
         
     | 
| 
      
 386 
     | 
    
         
            +
                    @live_thread_pool_executor ||= Concurrent::CachedThreadPool.new(name: "action_controller.live")
         
     | 
| 
       376 
387 
     | 
    
         
             
                  end
         
     | 
| 
       377 
388 
     | 
    
         | 
| 
       378 
389 
     | 
    
         
             
                  def log_error(exception)
         
     | 
| 
         @@ -29,6 +29,9 @@ module ActionController # :nodoc: 
     | 
|
| 
       29 
29 
     | 
    
         
             
                  # datastore as your general caches, you can pass a custom store in the `store`
         
     | 
| 
       30 
30 
     | 
    
         
             
                  # parameter.
         
     | 
| 
       31 
31 
     | 
    
         
             
                  #
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # If you want to use multiple rate limits per controller, you need to give each of
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # them and explicit name via the `name:` option.
         
     | 
| 
      
 34 
     | 
    
         
            +
                  #
         
     | 
| 
       32 
35 
     | 
    
         
             
                  # Examples:
         
     | 
| 
       33 
36 
     | 
    
         
             
                  #
         
     | 
| 
       34 
37 
     | 
    
         
             
                  #     class SessionsController < ApplicationController
         
     | 
| 
         @@ -44,14 +47,20 @@ module ActionController # :nodoc: 
     | 
|
| 
       44 
47 
     | 
    
         
             
                  #       RATE_LIMIT_STORE = ActiveSupport::Cache::RedisCacheStore.new(url: ENV["REDIS_URL"])
         
     | 
| 
       45 
48 
     | 
    
         
             
                  #       rate_limit to: 10, within: 3.minutes, store: RATE_LIMIT_STORE
         
     | 
| 
       46 
49 
     | 
    
         
             
                  #     end
         
     | 
| 
       47 
     | 
    
         
            -
                   
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
                  #
         
     | 
| 
      
 51 
     | 
    
         
            +
                  #     class SessionsController < ApplicationController
         
     | 
| 
      
 52 
     | 
    
         
            +
                  #       rate_limit to: 3, within: 2.seconds, name: "short-term"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  #       rate_limit to: 10, within: 5.minutes, name: "long-term"
         
     | 
| 
      
 54 
     | 
    
         
            +
                  #     end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def rate_limit(to:, within:, by: -> { request.remote_ip }, with: -> { head :too_many_requests }, store: cache_store, name: nil, **options)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    before_action -> { rate_limiting(to: to, within: within, by: by, with: with, store: store, name: name) }, **options
         
     | 
| 
       49 
57 
     | 
    
         
             
                  end
         
     | 
| 
       50 
58 
     | 
    
         
             
                end
         
     | 
| 
       51 
59 
     | 
    
         | 
| 
       52 
60 
     | 
    
         
             
                private
         
     | 
| 
       53 
     | 
    
         
            -
                  def rate_limiting(to:, within:, by:, with:, store:)
         
     | 
| 
       54 
     | 
    
         
            -
                     
     | 
| 
      
 61 
     | 
    
         
            +
                  def rate_limiting(to:, within:, by:, with:, store:, name:)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    cache_key = ["rate-limit", controller_path, name, instance_exec(&by)].compact.join(":")
         
     | 
| 
      
 63 
     | 
    
         
            +
                    count = store.increment(cache_key, 1, expires_in: within)
         
     | 
| 
       55 
64 
     | 
    
         
             
                    if count && count > to
         
     | 
| 
       56 
65 
     | 
    
         
             
                      ActiveSupport::Notifications.instrument("rate_limit.action_controller", request: request) do
         
     | 
| 
       57 
66 
     | 
    
         
             
                        instance_exec(&with)
         
     | 
| 
         @@ -154,7 +154,8 @@ module ActionController 
     | 
|
| 
       154 
154 
     | 
    
         
             
                end
         
     | 
| 
       155 
155 
     | 
    
         | 
| 
       156 
156 
     | 
    
         
             
                add :json do |json, options|
         
     | 
| 
       157 
     | 
    
         
            -
                   
     | 
| 
      
 157 
     | 
    
         
            +
                  json_options = options.except(:callback, :content_type, :status)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  json = json.to_json(json_options) unless json.kind_of?(String)
         
     | 
| 
       158 
159 
     | 
    
         | 
| 
       159 
160 
     | 
    
         
             
                  if options[:callback].present?
         
     | 
| 
       160 
161 
     | 
    
         
             
                    if media_type.nil? || media_type == Mime[:json]
         
     | 
| 
         @@ -165,95 +165,16 @@ module ActionController # :nodoc: 
     | 
|
| 
       165 
165 
     | 
    
         
             
              #
         
     | 
| 
       166 
166 
     | 
    
         
             
              # ## Web server support
         
     | 
| 
       167 
167 
     | 
    
         
             
              #
         
     | 
| 
       168 
     | 
    
         
            -
              #  
     | 
| 
       169 
     | 
    
         
            -
              # instructions for each of them.
         
     | 
| 
       170 
     | 
    
         
            -
              #
         
     | 
| 
       171 
     | 
    
         
            -
              # #### Unicorn
         
     | 
| 
       172 
     | 
    
         
            -
              #
         
     | 
| 
       173 
     | 
    
         
            -
              # Unicorn supports streaming but it needs to be configured. For this, you need
         
     | 
| 
       174 
     | 
    
         
            -
              # to create a config file as follow:
         
     | 
| 
       175 
     | 
    
         
            -
              #
         
     | 
| 
       176 
     | 
    
         
            -
              #     # unicorn.config.rb
         
     | 
| 
       177 
     | 
    
         
            -
              #     listen 3000, tcp_nopush: false
         
     | 
| 
       178 
     | 
    
         
            -
              #
         
     | 
| 
       179 
     | 
    
         
            -
              # And use it on initialization:
         
     | 
| 
       180 
     | 
    
         
            -
              #
         
     | 
| 
       181 
     | 
    
         
            -
              #     unicorn_rails --config-file unicorn.config.rb
         
     | 
| 
       182 
     | 
    
         
            -
              #
         
     | 
| 
       183 
     | 
    
         
            -
              # You may also want to configure other parameters like `:tcp_nodelay`.
         
     | 
| 
       184 
     | 
    
         
            -
              #
         
     | 
| 
       185 
     | 
    
         
            -
              # For more information, please check the
         
     | 
| 
       186 
     | 
    
         
            -
              # [documentation](https://bogomips.org/unicorn/Unicorn/Configurator.html#method-
         
     | 
| 
       187 
     | 
    
         
            -
              # i-listen).
         
     | 
| 
       188 
     | 
    
         
            -
              #
         
     | 
| 
       189 
     | 
    
         
            -
              # If you are using Unicorn with NGINX, you may need to tweak NGINX. Streaming
         
     | 
| 
       190 
     | 
    
         
            -
              # should work out of the box on Rainbows.
         
     | 
| 
       191 
     | 
    
         
            -
              #
         
     | 
| 
       192 
     | 
    
         
            -
              # #### Passenger
         
     | 
| 
       193 
     | 
    
         
            -
              #
         
     | 
| 
       194 
     | 
    
         
            -
              # Phusion Passenger with NGINX, offers two streaming mechanisms out of the box.
         
     | 
| 
       195 
     | 
    
         
            -
              #
         
     | 
| 
       196 
     | 
    
         
            -
              # 1.  NGINX response buffering mechanism which is dependent on the value of
         
     | 
| 
       197 
     | 
    
         
            -
              #     `passenger_buffer_response` option (default is "off").
         
     | 
| 
       198 
     | 
    
         
            -
              # 2.  Passenger buffering system which is always 'on' irrespective of the value
         
     | 
| 
       199 
     | 
    
         
            -
              #     of `passenger_buffer_response`.
         
     | 
| 
       200 
     | 
    
         
            -
              #
         
     | 
| 
       201 
     | 
    
         
            -
              #
         
     | 
| 
       202 
     | 
    
         
            -
              # When `passenger_buffer_response` is turned "on", then streaming would be done
         
     | 
| 
       203 
     | 
    
         
            -
              # at the NGINX level which waits until the application is done sending the
         
     | 
| 
       204 
     | 
    
         
            -
              # response back to the client.
         
     | 
| 
       205 
     | 
    
         
            -
              #
         
     | 
| 
       206 
     | 
    
         
            -
              # For more information, please check the [documentation]
         
     | 
| 
       207 
     | 
    
         
            -
              # (https://www.phusionpassenger.com/docs/references/config_reference/nginx/#passenger_buffer_response).
         
     | 
| 
      
 168 
     | 
    
         
            +
              # Rack 3+ compatible servers all support streaming.
         
     | 
| 
       208 
169 
     | 
    
         
             
              module Streaming
         
     | 
| 
       209 
     | 
    
         
            -
                class Body # :nodoc:
         
     | 
| 
       210 
     | 
    
         
            -
                  TERM = "\r\n"
         
     | 
| 
       211 
     | 
    
         
            -
                  TAIL = "0#{TERM}"
         
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
     | 
    
         
            -
                  # Store the response body to be chunked.
         
     | 
| 
       214 
     | 
    
         
            -
                  def initialize(body)
         
     | 
| 
       215 
     | 
    
         
            -
                    @body = body
         
     | 
| 
       216 
     | 
    
         
            -
                  end
         
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
                  # For each element yielded by the response body, yield the element in chunked
         
     | 
| 
       219 
     | 
    
         
            -
                  # encoding.
         
     | 
| 
       220 
     | 
    
         
            -
                  def each(&block)
         
     | 
| 
       221 
     | 
    
         
            -
                    term = TERM
         
     | 
| 
       222 
     | 
    
         
            -
                    @body.each do |chunk|
         
     | 
| 
       223 
     | 
    
         
            -
                      size = chunk.bytesize
         
     | 
| 
       224 
     | 
    
         
            -
                      next if size == 0
         
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
                      yield [size.to_s(16), term, chunk.b, term].join
         
     | 
| 
       227 
     | 
    
         
            -
                    end
         
     | 
| 
       228 
     | 
    
         
            -
                    yield TAIL
         
     | 
| 
       229 
     | 
    
         
            -
                    yield term
         
     | 
| 
       230 
     | 
    
         
            -
                  end
         
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
       232 
     | 
    
         
            -
                  # Close the response body if the response body supports it.
         
     | 
| 
       233 
     | 
    
         
            -
                  def close
         
     | 
| 
       234 
     | 
    
         
            -
                    @body.close if @body.respond_to?(:close)
         
     | 
| 
       235 
     | 
    
         
            -
                  end
         
     | 
| 
       236 
     | 
    
         
            -
                end
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
170 
     | 
    
         
             
                private
         
     | 
| 
       239 
     | 
    
         
            -
                  # Set proper cache control and transfer encoding when streaming
         
     | 
| 
       240 
     | 
    
         
            -
                  def _process_options(options)
         
     | 
| 
       241 
     | 
    
         
            -
                    super
         
     | 
| 
       242 
     | 
    
         
            -
                    if options[:stream]
         
     | 
| 
       243 
     | 
    
         
            -
                      if request.version == "HTTP/1.0"
         
     | 
| 
       244 
     | 
    
         
            -
                        options.delete(:stream)
         
     | 
| 
       245 
     | 
    
         
            -
                      else
         
     | 
| 
       246 
     | 
    
         
            -
                        headers["Cache-Control"] ||= "no-cache"
         
     | 
| 
       247 
     | 
    
         
            -
                        headers["Transfer-Encoding"] = "chunked"
         
     | 
| 
       248 
     | 
    
         
            -
                        headers.delete("Content-Length")
         
     | 
| 
       249 
     | 
    
         
            -
                      end
         
     | 
| 
       250 
     | 
    
         
            -
                    end
         
     | 
| 
       251 
     | 
    
         
            -
                  end
         
     | 
| 
       252 
     | 
    
         
            -
             
     | 
| 
       253 
171 
     | 
    
         
             
                  # Call render_body if we are streaming instead of usual `render`.
         
     | 
| 
       254 
172 
     | 
    
         
             
                  def _render_template(options)
         
     | 
| 
       255 
173 
     | 
    
         
             
                    if options.delete(:stream)
         
     | 
| 
       256 
     | 
    
         
            -
                       
     | 
| 
      
 174 
     | 
    
         
            +
                      # It shoudn't be necessary to set this.
         
     | 
| 
      
 175 
     | 
    
         
            +
                      headers["cache-control"] ||= "no-cache"
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                      view_renderer.render_body(view_context, options)
         
     | 
| 
       257 
178 
     | 
    
         
             
                    else
         
     | 
| 
       258 
179 
     | 
    
         
             
                      super
         
     | 
| 
       259 
180 
     | 
    
         
             
                    end
         
     |