actionpack 7.1.5.1 → 8.1.2

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.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +308 -523
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller/asset_paths.rb +6 -2
  5. data/lib/abstract_controller/base.rb +104 -105
  6. data/lib/abstract_controller/caching/fragments.rb +50 -53
  7. data/lib/abstract_controller/caching.rb +8 -3
  8. data/lib/abstract_controller/callbacks.rb +70 -62
  9. data/lib/abstract_controller/collector.rb +7 -7
  10. data/lib/abstract_controller/deprecator.rb +2 -0
  11. data/lib/abstract_controller/error.rb +2 -0
  12. data/lib/abstract_controller/helpers.rb +71 -84
  13. data/lib/abstract_controller/logger.rb +4 -1
  14. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  15. data/lib/abstract_controller/rendering.rb +13 -13
  16. data/lib/abstract_controller/translation.rb +12 -13
  17. data/lib/abstract_controller/url_for.rb +8 -6
  18. data/lib/abstract_controller.rb +2 -0
  19. data/lib/action_controller/api/api_rendering.rb +2 -0
  20. data/lib/action_controller/api.rb +76 -72
  21. data/lib/action_controller/base.rb +199 -126
  22. data/lib/action_controller/caching.rb +16 -14
  23. data/lib/action_controller/deprecator.rb +2 -0
  24. data/lib/action_controller/form_builder.rb +21 -18
  25. data/lib/action_controller/log_subscriber.rb +23 -2
  26. data/lib/action_controller/metal/allow_browser.rb +133 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  28. data/lib/action_controller/metal/conditional_get.rb +217 -175
  29. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  30. data/lib/action_controller/metal/cookies.rb +4 -2
  31. data/lib/action_controller/metal/data_streaming.rb +72 -63
  32. data/lib/action_controller/metal/default_headers.rb +5 -3
  33. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  34. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  35. data/lib/action_controller/metal/exceptions.rb +16 -9
  36. data/lib/action_controller/metal/flash.rb +13 -14
  37. data/lib/action_controller/metal/head.rb +15 -11
  38. data/lib/action_controller/metal/helpers.rb +63 -55
  39. data/lib/action_controller/metal/http_authentication.rb +209 -201
  40. data/lib/action_controller/metal/implicit_render.rb +17 -15
  41. data/lib/action_controller/metal/instrumentation.rb +16 -14
  42. data/lib/action_controller/metal/live.rb +177 -128
  43. data/lib/action_controller/metal/logging.rb +6 -4
  44. data/lib/action_controller/metal/mime_responds.rb +151 -142
  45. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  46. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  47. data/lib/action_controller/metal/permissions_policy.rb +22 -12
  48. data/lib/action_controller/metal/rate_limiting.rb +92 -0
  49. data/lib/action_controller/metal/redirecting.rb +213 -94
  50. data/lib/action_controller/metal/renderers.rb +78 -57
  51. data/lib/action_controller/metal/rendering.rb +111 -77
  52. data/lib/action_controller/metal/request_forgery_protection.rb +182 -143
  53. data/lib/action_controller/metal/rescue.rb +20 -9
  54. data/lib/action_controller/metal/streaming.rb +118 -195
  55. data/lib/action_controller/metal/strong_parameters.rb +720 -530
  56. data/lib/action_controller/metal/testing.rb +2 -0
  57. data/lib/action_controller/metal/url_for.rb +17 -15
  58. data/lib/action_controller/metal.rb +86 -60
  59. data/lib/action_controller/railtie.rb +36 -15
  60. data/lib/action_controller/railties/helpers.rb +2 -0
  61. data/lib/action_controller/renderer.rb +41 -36
  62. data/lib/action_controller/structured_event_subscriber.rb +116 -0
  63. data/lib/action_controller/template_assertions.rb +4 -2
  64. data/lib/action_controller/test_case.rb +160 -131
  65. data/lib/action_controller.rb +5 -1
  66. data/lib/action_dispatch/constants.rb +8 -0
  67. data/lib/action_dispatch/deprecator.rb +2 -0
  68. data/lib/action_dispatch/http/cache.rb +163 -35
  69. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +54 -39
  71. data/lib/action_dispatch/http/filter_parameters.rb +14 -8
  72. data/lib/action_dispatch/http/filter_redirect.rb +22 -1
  73. data/lib/action_dispatch/http/headers.rb +22 -22
  74. data/lib/action_dispatch/http/mime_negotiation.rb +89 -41
  75. data/lib/action_dispatch/http/mime_type.rb +25 -21
  76. data/lib/action_dispatch/http/mime_types.rb +3 -0
  77. data/lib/action_dispatch/http/param_builder.rb +187 -0
  78. data/lib/action_dispatch/http/param_error.rb +26 -0
  79. data/lib/action_dispatch/http/parameters.rb +14 -12
  80. data/lib/action_dispatch/http/permissions_policy.rb +25 -36
  81. data/lib/action_dispatch/http/query_parser.rb +55 -0
  82. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  83. data/lib/action_dispatch/http/request.rb +141 -92
  84. data/lib/action_dispatch/http/response.rb +137 -77
  85. data/lib/action_dispatch/http/upload.rb +18 -16
  86. data/lib/action_dispatch/http/url.rb +187 -89
  87. data/lib/action_dispatch/journey/formatter.rb +21 -9
  88. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  89. data/lib/action_dispatch/journey/gtg/simulator.rb +34 -11
  90. data/lib/action_dispatch/journey/gtg/transition_table.rb +47 -53
  91. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  92. data/lib/action_dispatch/journey/nodes/node.rb +8 -6
  93. data/lib/action_dispatch/journey/parser.rb +99 -195
  94. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  95. data/lib/action_dispatch/journey/route.rb +54 -38
  96. data/lib/action_dispatch/journey/router/utils.rb +22 -27
  97. data/lib/action_dispatch/journey/router.rb +63 -83
  98. data/lib/action_dispatch/journey/routes.rb +11 -2
  99. data/lib/action_dispatch/journey/scanner.rb +46 -42
  100. data/lib/action_dispatch/journey/visitors.rb +57 -23
  101. data/lib/action_dispatch/journey/visualizer/fsm.js +4 -6
  102. data/lib/action_dispatch/journey.rb +2 -0
  103. data/lib/action_dispatch/log_subscriber.rb +7 -1
  104. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  105. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  106. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  107. data/lib/action_dispatch/middleware/cookies.rb +125 -106
  108. data/lib/action_dispatch/middleware/debug_exceptions.rb +37 -8
  109. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  110. data/lib/action_dispatch/middleware/debug_view.rb +13 -5
  111. data/lib/action_dispatch/middleware/exception_wrapper.rb +18 -23
  112. data/lib/action_dispatch/middleware/executor.rb +19 -4
  113. data/lib/action_dispatch/middleware/flash.rb +63 -51
  114. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  115. data/lib/action_dispatch/middleware/public_exceptions.rb +14 -12
  116. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  117. data/lib/action_dispatch/middleware/remote_ip.rb +87 -77
  118. data/lib/action_dispatch/middleware/request_id.rb +16 -10
  119. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  120. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  121. data/lib/action_dispatch/middleware/session/cache_store.rb +30 -8
  122. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  123. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  124. data/lib/action_dispatch/middleware/show_exceptions.rb +16 -16
  125. data/lib/action_dispatch/middleware/ssl.rb +53 -40
  126. data/lib/action_dispatch/middleware/stack.rb +11 -10
  127. data/lib/action_dispatch/middleware/static.rb +33 -31
  128. data/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb +1 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +3 -5
  130. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +9 -5
  131. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +1 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +3 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +50 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -0
  141. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  142. data/lib/action_dispatch/railtie.rb +23 -3
  143. data/lib/action_dispatch/request/session.rb +24 -21
  144. data/lib/action_dispatch/request/utils.rb +11 -3
  145. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  146. data/lib/action_dispatch/routing/inspector.rb +85 -60
  147. data/lib/action_dispatch/routing/mapper.rb +1031 -851
  148. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  149. data/lib/action_dispatch/routing/redirection.rb +47 -39
  150. data/lib/action_dispatch/routing/route_set.rb +79 -56
  151. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  152. data/lib/action_dispatch/routing/url_for.rb +130 -125
  153. data/lib/action_dispatch/routing.rb +150 -148
  154. data/lib/action_dispatch/structured_event_subscriber.rb +20 -0
  155. data/lib/action_dispatch/system_test_case.rb +91 -81
  156. data/lib/action_dispatch/system_testing/browser.rb +16 -23
  157. data/lib/action_dispatch/system_testing/driver.rb +2 -0
  158. data/lib/action_dispatch/system_testing/server.rb +2 -0
  159. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +34 -23
  160. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  161. data/lib/action_dispatch/testing/assertion_response.rb +9 -7
  162. data/lib/action_dispatch/testing/assertions/response.rb +52 -25
  163. data/lib/action_dispatch/testing/assertions/routing.rb +168 -87
  164. data/lib/action_dispatch/testing/assertions.rb +2 -0
  165. data/lib/action_dispatch/testing/integration.rb +233 -223
  166. data/lib/action_dispatch/testing/request_encoder.rb +11 -9
  167. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  168. data/lib/action_dispatch/testing/test_process.rb +11 -8
  169. data/lib/action_dispatch/testing/test_request.rb +3 -1
  170. data/lib/action_dispatch/testing/test_response.rb +27 -26
  171. data/lib/action_dispatch.rb +36 -32
  172. data/lib/action_pack/gem_version.rb +6 -4
  173. data/lib/action_pack/version.rb +3 -1
  174. data/lib/action_pack.rb +17 -16
  175. metadata +36 -32
  176. data/lib/action_dispatch/journey/parser.y +0 -50
  177. data/lib/action_dispatch/journey/parser_extras.rb +0 -31
@@ -1,257 +1,180 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionController # :nodoc:
4
- # = Action Controller \Streaming
6
+ # # Action Controller Streaming
5
7
  #
6
8
  # Allows views to be streamed back to the client as they are rendered.
7
9
  #
8
- # By default, \Rails renders views by first rendering the template
9
- # and then the layout. The response is sent to the client after the whole
10
- # template is rendered, all queries are made, and the layout is processed.
10
+ # By default, Rails renders views by first rendering the template and then the
11
+ # layout. The response is sent to the client after the whole template is
12
+ # rendered, all queries are made, and the layout is processed.
11
13
  #
12
- # \Streaming inverts the rendering flow by rendering the layout first and
14
+ # Streaming inverts the rendering flow by rendering the layout first and
13
15
  # subsequently each part of the layout as they are processed. This allows the
14
- # header of the HTML (which is usually in the layout) to be streamed back
15
- # to client very quickly, enabling JavaScripts and stylesheets to be loaded
16
- # earlier than usual.
17
- #
18
- # Several Rack middlewares may not work and you need to be careful when streaming.
19
- # This is covered in more detail below, see the Streaming@Middlewares section.
20
- #
21
- # \Streaming can be added to a given template easily, all you need to do is
22
- # to pass the +:stream+ option to +render+.
23
- #
24
- # class PostsController
25
- # def index
26
- # @posts = Post.all
27
- # render stream: true
16
+ # header of the HTML (which is usually in the layout) to be streamed back to
17
+ # client very quickly, enabling JavaScripts and stylesheets to be loaded earlier
18
+ # than usual.
19
+ #
20
+ # Several Rack middlewares may not work and you need to be careful when
21
+ # streaming. This is covered in more detail below, see the Streaming@Middlewares
22
+ # section.
23
+ #
24
+ # Streaming can be added to a given template easily, all you need to do is to
25
+ # pass the `:stream` option to `render`.
26
+ #
27
+ # class PostsController
28
+ # def index
29
+ # @posts = Post.all
30
+ # render stream: true
31
+ # end
28
32
  # end
29
- # end
30
33
  #
31
- # == When to use streaming
34
+ # ## When to use streaming
32
35
  #
33
- # \Streaming may be considered to be overkill for lightweight actions like
34
- # +new+ or +edit+. The real benefit of streaming is on expensive actions
35
- # that, for example, do a lot of queries on the database.
36
+ # Streaming may be considered to be overkill for lightweight actions like `new`
37
+ # or `edit`. The real benefit of streaming is on expensive actions that, for
38
+ # example, do a lot of queries on the database.
36
39
  #
37
- # In such actions, you want to delay queries execution as much as you can.
38
- # For example, imagine the following +dashboard+ action:
40
+ # In such actions, you want to delay queries execution as much as you can. For
41
+ # example, imagine the following `dashboard` action:
39
42
  #
40
- # def dashboard
41
- # @posts = Post.all
42
- # @pages = Page.all
43
- # @articles = Article.all
44
- # end
43
+ # def dashboard
44
+ # @posts = Post.all
45
+ # @pages = Page.all
46
+ # @articles = Article.all
47
+ # end
45
48
  #
46
49
  # Most of the queries here are happening in the controller. In order to benefit
47
50
  # from streaming you would want to rewrite it as:
48
51
  #
49
- # def dashboard
50
- # # Allow lazy execution of the queries
51
- # @posts = Post.all
52
- # @pages = Page.all
53
- # @articles = Article.all
54
- # render stream: true
55
- # end
52
+ # def dashboard
53
+ # # Allow lazy execution of the queries
54
+ # @posts = Post.all
55
+ # @pages = Page.all
56
+ # @articles = Article.all
57
+ # render stream: true
58
+ # end
56
59
  #
57
- # Notice that +:stream+ only works with templates. \Rendering +:json+
58
- # or +:xml+ with +:stream+ won't work.
60
+ # Notice that `:stream` only works with templates. Rendering `:json` or `:xml`
61
+ # with `:stream` won't work.
59
62
  #
60
- # == Communication between layout and template
63
+ # ## Communication between layout and template
61
64
  #
62
- # When streaming, rendering happens top-down instead of inside-out.
63
- # \Rails starts with the layout, and the template is rendered later,
64
- # when its +yield+ is reached.
65
+ # When streaming, rendering happens top-down instead of inside-out. Rails starts
66
+ # with the layout, and the template is rendered later, when its `yield` is
67
+ # reached.
65
68
  #
66
- # This means that, if your application currently relies on instance
67
- # variables set in the template to be used in the layout, they won't
68
- # work once you move to streaming. The proper way to communicate
69
- # between layout and template, regardless of whether you use streaming
70
- # or not, is by using +content_for+, +provide+, and +yield+.
69
+ # This means that, if your application currently relies on instance variables
70
+ # set in the template to be used in the layout, they won't work once you move to
71
+ # streaming. The proper way to communicate between layout and template,
72
+ # regardless of whether you use streaming or not, is by using `content_for`,
73
+ # `provide`, and `yield`.
71
74
  #
72
- # Take a simple example where the layout expects the template to tell
73
- # which title to use:
75
+ # Take a simple example where the layout expects the template to tell which
76
+ # title to use:
74
77
  #
75
- # <html>
76
- # <head><title><%= yield :title %></title></head>
77
- # <body><%= yield %></body>
78
- # </html>
78
+ # <html>
79
+ # <head><title><%= yield :title %></title></head>
80
+ # <body><%= yield %></body>
81
+ # </html>
79
82
  #
80
- # You would use +content_for+ in your template to specify the title:
83
+ # You would use `content_for` in your template to specify the title:
81
84
  #
82
- # <%= content_for :title, "Main" %>
83
- # Hello
85
+ # <%= content_for :title, "Main" %>
86
+ # Hello
84
87
  #
85
88
  # And the final result would be:
86
89
  #
87
- # <html>
88
- # <head><title>Main</title></head>
89
- # <body>Hello</body>
90
- # </html>
90
+ # <html>
91
+ # <head><title>Main</title></head>
92
+ # <body>Hello</body>
93
+ # </html>
91
94
  #
92
- # However, if +content_for+ is called several times, the final result
93
- # would have all calls concatenated. For instance, if we have the following
94
- # template:
95
+ # However, if `content_for` is called several times, the final result would have
96
+ # all calls concatenated. For instance, if we have the following template:
95
97
  #
96
- # <%= content_for :title, "Main" %>
97
- # Hello
98
- # <%= content_for :title, " page" %>
98
+ # <%= content_for :title, "Main" %>
99
+ # Hello
100
+ # <%= content_for :title, " page" %>
99
101
  #
100
102
  # The final result would be:
101
103
  #
102
- # <html>
103
- # <head><title>Main page</title></head>
104
- # <body>Hello</body>
105
- # </html>
104
+ # <html>
105
+ # <head><title>Main page</title></head>
106
+ # <body>Hello</body>
107
+ # </html>
106
108
  #
107
- # This means that, if you have <code>yield :title</code> in your layout
108
- # and you want to use streaming, you would have to render the whole template
109
- # (and eventually trigger all queries) before streaming the title and all
110
- # assets, which defeats the purpose of streaming. Alternatively, you can use
111
- # a helper called +provide+ that does the same as +content_for+ but tells the
112
- # layout to stop searching for other entries and continue rendering.
109
+ # This means that, if you have `yield :title` in your layout and you want to use
110
+ # streaming, you would have to render the whole template (and eventually trigger
111
+ # all queries) before streaming the title and all assets, which defeats the
112
+ # purpose of streaming. Alternatively, you can use a helper called `provide`
113
+ # that does the same as `content_for` but tells the layout to stop searching for
114
+ # other entries and continue rendering.
113
115
  #
114
- # For instance, the template above using +provide+ would be:
116
+ # For instance, the template above using `provide` would be:
115
117
  #
116
- # <%= provide :title, "Main" %>
117
- # Hello
118
- # <%= content_for :title, " page" %>
118
+ # <%= provide :title, "Main" %>
119
+ # Hello
120
+ # <%= content_for :title, " page" %>
119
121
  #
120
122
  # Resulting in:
121
123
  #
122
- # <html>
123
- # <head><title>Main</title></head>
124
- # <body>Hello</body>
125
- # </html>
124
+ # <html>
125
+ # <head><title>Main</title></head>
126
+ # <body>Hello</body>
127
+ # </html>
126
128
  #
127
- # That said, when streaming, you need to properly check your templates
128
- # and choose when to use +provide+ and +content_for+.
129
+ # That said, when streaming, you need to properly check your templates and
130
+ # choose when to use `provide` and `content_for`.
129
131
  #
130
132
  # See also ActionView::Helpers::CaptureHelper for more information.
131
133
  #
132
- # == Headers, cookies, session, and flash
134
+ # ## Headers, cookies, session, and flash
133
135
  #
134
- # When streaming, the HTTP headers are sent to the client right before
135
- # it renders the first line. This means that, modifying headers, cookies,
136
- # session or flash after the template starts rendering will not propagate
137
- # to the client.
136
+ # When streaming, the HTTP headers are sent to the client right before it
137
+ # renders the first line. This means that, modifying headers, cookies, session
138
+ # or flash after the template starts rendering will not propagate to the client.
138
139
  #
139
- # == Middlewares
140
+ # ## Middlewares
140
141
  #
141
- # Middlewares that need to manipulate the body won't work with streaming.
142
- # You should disable those middlewares whenever streaming in development
143
- # or production. For instance, +Rack::Bug+ won't work when streaming as it
144
- # needs to inject contents in the HTML body.
142
+ # Middlewares that need to manipulate the body won't work with streaming. You
143
+ # should disable those middlewares whenever streaming in development or
144
+ # production. For instance, `Rack::Bug` won't work when streaming as it needs to
145
+ # inject contents in the HTML body.
145
146
  #
146
- # Also +Rack::Cache+ won't work with streaming as it does not support
147
- # streaming bodies yet. Whenever streaming +Cache-Control+ is automatically
148
- # set to "no-cache".
147
+ # Also `Rack::Cache` won't work with streaming as it does not support streaming
148
+ # bodies yet. Whenever streaming `Cache-Control` is automatically set to
149
+ # "no-cache".
149
150
  #
150
- # == Errors
151
+ # ## Errors
151
152
  #
152
153
  # When it comes to streaming, exceptions get a bit more complicated. This
153
- # happens because part of the template was already rendered and streamed to
154
- # the client, making it impossible to render a whole exception page.
155
- #
156
- # Currently, when an exception happens in development or production, \Rails
157
- # will automatically stream to the client:
158
- #
159
- # "><script>window.location = "/500.html"</script></html>
160
- #
161
- # The first two characters (<tt>"></tt>) are required in case the exception
162
- # happens while rendering attributes for a given tag. You can check the real
163
- # cause for the exception in your logger.
164
- #
165
- # == Web server support
166
- #
167
- # Not all web servers support streaming out-of-the-box. You need to check
168
- # the instructions for each of them.
169
- #
170
- # ==== Unicorn
171
- #
172
- # Unicorn supports streaming but it needs to be configured. For this, you
173
- # need to create a config file as follow:
174
- #
175
- # # unicorn.config.rb
176
- # listen 3000, tcp_nopush: false
154
+ # happens because part of the template was already rendered and streamed to the
155
+ # client, making it impossible to render a whole exception page.
177
156
  #
178
- # And use it on initialization:
157
+ # Currently, when an exception happens in development or production, Rails will
158
+ # automatically stream to the client:
179
159
  #
180
- # unicorn_rails --config-file unicorn.config.rb
160
+ # "><script>window.location = "/500.html"</script></html>
181
161
  #
182
- # You may also want to configure other parameters like <tt>:tcp_nodelay</tt>.
162
+ # The first two characters (`">`) are required in case the exception happens
163
+ # while rendering attributes for a given tag. You can check the real cause for
164
+ # the exception in your logger.
183
165
  #
184
- # For more information, please check the
185
- # {documentation}[https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-listen].
186
- #
187
- # If you are using Unicorn with NGINX, you may need to tweak NGINX.
188
- # \Streaming should work out of the box on Rainbows.
189
- #
190
- # ==== Passenger
191
- #
192
- # Phusion Passenger with NGINX, offers two streaming mechanisms out of the box.
193
- #
194
- # 1. NGINX response buffering mechanism which is dependent on the value of
195
- # +passenger_buffer_response+ option (default is "off").
196
- # 2. Passenger buffering system which is always 'on' irrespective of the value
197
- # of +passenger_buffer_response+.
198
- #
199
- # When +passenger_buffer_response+ is turned "on", then streaming would be
200
- # done at the NGINX level which waits until the application is done sending
201
- # the response back to the client.
202
- #
203
- # For more information, please check the
204
- # {documentation}[https://www.phusionpassenger.com/docs/references/config_reference/nginx/#passenger_buffer_response].
166
+ # ## Web server support
205
167
  #
168
+ # Rack 3+ compatible servers all support streaming.
206
169
  module Streaming
207
- class Body # :nodoc:
208
- TERM = "\r\n"
209
- TAIL = "0#{TERM}"
210
-
211
- # Store the response body to be chunked.
212
- def initialize(body)
213
- @body = body
214
- end
215
-
216
- # For each element yielded by the response body, yield
217
- # the element in chunked encoding.
218
- def each(&block)
219
- term = TERM
220
- @body.each do |chunk|
221
- size = chunk.bytesize
222
- next if size == 0
223
-
224
- yield [size.to_s(16), term, chunk.b, term].join
225
- end
226
- yield TAIL
227
- yield term
228
- end
229
-
230
- # Close the response body if the response body supports it.
231
- def close
232
- @body.close if @body.respond_to?(:close)
233
- end
234
- end
235
-
236
170
  private
237
- # Set proper cache control and transfer encoding when streaming
238
- def _process_options(options)
239
- super
240
- if options[:stream]
241
- if request.version == "HTTP/1.0"
242
- options.delete(:stream)
243
- else
244
- headers["Cache-Control"] ||= "no-cache"
245
- headers["Transfer-Encoding"] = "chunked"
246
- headers.delete("Content-Length")
247
- end
248
- end
249
- end
250
-
251
- # Call render_body if we are streaming instead of usual +render+.
171
+ # Call render_body if we are streaming instead of usual `render`.
252
172
  def _render_template(options)
253
173
  if options.delete(:stream)
254
- Body.new view_renderer.render_body(view_context, options)
174
+ # It shouldn't be necessary to set this.
175
+ headers["cache-control"] ||= "no-cache"
176
+
177
+ view_renderer.render_body(view_context, options)
255
178
  else
256
179
  super
257
180
  end