omg-actionpack 8.0.0.alpha1

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 (187) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +129 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +57 -0
  5. data/lib/abstract_controller/asset_paths.rb +14 -0
  6. data/lib/abstract_controller/base.rb +299 -0
  7. data/lib/abstract_controller/caching/fragments.rb +149 -0
  8. data/lib/abstract_controller/caching.rb +68 -0
  9. data/lib/abstract_controller/callbacks.rb +265 -0
  10. data/lib/abstract_controller/collector.rb +44 -0
  11. data/lib/abstract_controller/deprecator.rb +9 -0
  12. data/lib/abstract_controller/error.rb +8 -0
  13. data/lib/abstract_controller/helpers.rb +243 -0
  14. data/lib/abstract_controller/logger.rb +16 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +25 -0
  16. data/lib/abstract_controller/rendering.rb +126 -0
  17. data/lib/abstract_controller/translation.rb +42 -0
  18. data/lib/abstract_controller/url_for.rb +37 -0
  19. data/lib/abstract_controller.rb +36 -0
  20. data/lib/action_controller/api/api_rendering.rb +18 -0
  21. data/lib/action_controller/api.rb +155 -0
  22. data/lib/action_controller/base.rb +332 -0
  23. data/lib/action_controller/caching.rb +49 -0
  24. data/lib/action_controller/deprecator.rb +9 -0
  25. data/lib/action_controller/form_builder.rb +55 -0
  26. data/lib/action_controller/log_subscriber.rb +96 -0
  27. data/lib/action_controller/metal/allow_browser.rb +123 -0
  28. data/lib/action_controller/metal/basic_implicit_render.rb +17 -0
  29. data/lib/action_controller/metal/conditional_get.rb +341 -0
  30. data/lib/action_controller/metal/content_security_policy.rb +86 -0
  31. data/lib/action_controller/metal/cookies.rb +20 -0
  32. data/lib/action_controller/metal/data_streaming.rb +154 -0
  33. data/lib/action_controller/metal/default_headers.rb +21 -0
  34. data/lib/action_controller/metal/etag_with_flash.rb +22 -0
  35. data/lib/action_controller/metal/etag_with_template_digest.rb +59 -0
  36. data/lib/action_controller/metal/exceptions.rb +106 -0
  37. data/lib/action_controller/metal/flash.rb +67 -0
  38. data/lib/action_controller/metal/head.rb +67 -0
  39. data/lib/action_controller/metal/helpers.rb +129 -0
  40. data/lib/action_controller/metal/http_authentication.rb +565 -0
  41. data/lib/action_controller/metal/implicit_render.rb +67 -0
  42. data/lib/action_controller/metal/instrumentation.rb +120 -0
  43. data/lib/action_controller/metal/live.rb +398 -0
  44. data/lib/action_controller/metal/logging.rb +22 -0
  45. data/lib/action_controller/metal/mime_responds.rb +337 -0
  46. data/lib/action_controller/metal/parameter_encoding.rb +84 -0
  47. data/lib/action_controller/metal/params_wrapper.rb +312 -0
  48. data/lib/action_controller/metal/permissions_policy.rb +38 -0
  49. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  50. data/lib/action_controller/metal/redirecting.rb +251 -0
  51. data/lib/action_controller/metal/renderers.rb +181 -0
  52. data/lib/action_controller/metal/rendering.rb +260 -0
  53. data/lib/action_controller/metal/request_forgery_protection.rb +667 -0
  54. data/lib/action_controller/metal/rescue.rb +33 -0
  55. data/lib/action_controller/metal/streaming.rb +183 -0
  56. data/lib/action_controller/metal/strong_parameters.rb +1546 -0
  57. data/lib/action_controller/metal/testing.rb +25 -0
  58. data/lib/action_controller/metal/url_for.rb +65 -0
  59. data/lib/action_controller/metal.rb +339 -0
  60. data/lib/action_controller/railtie.rb +149 -0
  61. data/lib/action_controller/railties/helpers.rb +26 -0
  62. data/lib/action_controller/renderer.rb +161 -0
  63. data/lib/action_controller/template_assertions.rb +13 -0
  64. data/lib/action_controller/test_case.rb +691 -0
  65. data/lib/action_controller.rb +80 -0
  66. data/lib/action_dispatch/constants.rb +34 -0
  67. data/lib/action_dispatch/deprecator.rb +9 -0
  68. data/lib/action_dispatch/http/cache.rb +249 -0
  69. data/lib/action_dispatch/http/content_disposition.rb +47 -0
  70. data/lib/action_dispatch/http/content_security_policy.rb +365 -0
  71. data/lib/action_dispatch/http/filter_parameters.rb +80 -0
  72. data/lib/action_dispatch/http/filter_redirect.rb +50 -0
  73. data/lib/action_dispatch/http/headers.rb +134 -0
  74. data/lib/action_dispatch/http/mime_negotiation.rb +187 -0
  75. data/lib/action_dispatch/http/mime_type.rb +389 -0
  76. data/lib/action_dispatch/http/mime_types.rb +54 -0
  77. data/lib/action_dispatch/http/parameters.rb +119 -0
  78. data/lib/action_dispatch/http/permissions_policy.rb +189 -0
  79. data/lib/action_dispatch/http/rack_cache.rb +67 -0
  80. data/lib/action_dispatch/http/request.rb +498 -0
  81. data/lib/action_dispatch/http/response.rb +556 -0
  82. data/lib/action_dispatch/http/upload.rb +107 -0
  83. data/lib/action_dispatch/http/url.rb +344 -0
  84. data/lib/action_dispatch/journey/formatter.rb +226 -0
  85. data/lib/action_dispatch/journey/gtg/builder.rb +149 -0
  86. data/lib/action_dispatch/journey/gtg/simulator.rb +50 -0
  87. data/lib/action_dispatch/journey/gtg/transition_table.rb +217 -0
  88. data/lib/action_dispatch/journey/nfa/dot.rb +27 -0
  89. data/lib/action_dispatch/journey/nodes/node.rb +208 -0
  90. data/lib/action_dispatch/journey/parser.rb +103 -0
  91. data/lib/action_dispatch/journey/path/pattern.rb +209 -0
  92. data/lib/action_dispatch/journey/route.rb +189 -0
  93. data/lib/action_dispatch/journey/router/utils.rb +105 -0
  94. data/lib/action_dispatch/journey/router.rb +151 -0
  95. data/lib/action_dispatch/journey/routes.rb +82 -0
  96. data/lib/action_dispatch/journey/scanner.rb +70 -0
  97. data/lib/action_dispatch/journey/visitors.rb +267 -0
  98. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  99. data/lib/action_dispatch/journey/visualizer/fsm.js +159 -0
  100. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  101. data/lib/action_dispatch/journey.rb +7 -0
  102. data/lib/action_dispatch/log_subscriber.rb +25 -0
  103. data/lib/action_dispatch/middleware/actionable_exceptions.rb +46 -0
  104. data/lib/action_dispatch/middleware/assume_ssl.rb +27 -0
  105. data/lib/action_dispatch/middleware/callbacks.rb +38 -0
  106. data/lib/action_dispatch/middleware/cookies.rb +719 -0
  107. data/lib/action_dispatch/middleware/debug_exceptions.rb +206 -0
  108. data/lib/action_dispatch/middleware/debug_locks.rb +129 -0
  109. data/lib/action_dispatch/middleware/debug_view.rb +73 -0
  110. data/lib/action_dispatch/middleware/exception_wrapper.rb +350 -0
  111. data/lib/action_dispatch/middleware/executor.rb +32 -0
  112. data/lib/action_dispatch/middleware/flash.rb +318 -0
  113. data/lib/action_dispatch/middleware/host_authorization.rb +171 -0
  114. data/lib/action_dispatch/middleware/public_exceptions.rb +64 -0
  115. data/lib/action_dispatch/middleware/reloader.rb +16 -0
  116. data/lib/action_dispatch/middleware/remote_ip.rb +199 -0
  117. data/lib/action_dispatch/middleware/request_id.rb +50 -0
  118. data/lib/action_dispatch/middleware/server_timing.rb +78 -0
  119. data/lib/action_dispatch/middleware/session/abstract_store.rb +112 -0
  120. data/lib/action_dispatch/middleware/session/cache_store.rb +66 -0
  121. data/lib/action_dispatch/middleware/session/cookie_store.rb +129 -0
  122. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +34 -0
  123. data/lib/action_dispatch/middleware/show_exceptions.rb +88 -0
  124. data/lib/action_dispatch/middleware/ssl.rb +180 -0
  125. data/lib/action_dispatch/middleware/stack.rb +194 -0
  126. data/lib/action_dispatch/middleware/static.rb +192 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +22 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +17 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +36 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +62 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +12 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +9 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +35 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  141. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +16 -0
  142. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +284 -0
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +23 -0
  144. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  145. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  146. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  147. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  148. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  149. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  150. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  151. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  152. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  153. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +19 -0
  154. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +232 -0
  155. data/lib/action_dispatch/railtie.rb +77 -0
  156. data/lib/action_dispatch/request/session.rb +283 -0
  157. data/lib/action_dispatch/request/utils.rb +109 -0
  158. data/lib/action_dispatch/routing/endpoint.rb +19 -0
  159. data/lib/action_dispatch/routing/inspector.rb +323 -0
  160. data/lib/action_dispatch/routing/mapper.rb +2372 -0
  161. data/lib/action_dispatch/routing/polymorphic_routes.rb +363 -0
  162. data/lib/action_dispatch/routing/redirection.rb +218 -0
  163. data/lib/action_dispatch/routing/route_set.rb +958 -0
  164. data/lib/action_dispatch/routing/routes_proxy.rb +66 -0
  165. data/lib/action_dispatch/routing/url_for.rb +244 -0
  166. data/lib/action_dispatch/routing.rb +262 -0
  167. data/lib/action_dispatch/system_test_case.rb +206 -0
  168. data/lib/action_dispatch/system_testing/browser.rb +75 -0
  169. data/lib/action_dispatch/system_testing/driver.rb +85 -0
  170. data/lib/action_dispatch/system_testing/server.rb +33 -0
  171. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +164 -0
  172. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +23 -0
  173. data/lib/action_dispatch/testing/assertion_response.rb +48 -0
  174. data/lib/action_dispatch/testing/assertions/response.rb +114 -0
  175. data/lib/action_dispatch/testing/assertions/routing.rb +343 -0
  176. data/lib/action_dispatch/testing/assertions.rb +25 -0
  177. data/lib/action_dispatch/testing/integration.rb +694 -0
  178. data/lib/action_dispatch/testing/request_encoder.rb +60 -0
  179. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  180. data/lib/action_dispatch/testing/test_process.rb +57 -0
  181. data/lib/action_dispatch/testing/test_request.rb +73 -0
  182. data/lib/action_dispatch/testing/test_response.rb +58 -0
  183. data/lib/action_dispatch.rb +147 -0
  184. data/lib/action_pack/gem_version.rb +19 -0
  185. data/lib/action_pack/version.rb +12 -0
  186. data/lib/action_pack.rb +27 -0
  187. metadata +375 -0
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "action_dispatch"
6
+ require "action_dispatch/log_subscriber"
7
+ require "active_support/messages/rotation_configuration"
8
+
9
+ module ActionDispatch
10
+ class Railtie < Rails::Railtie # :nodoc:
11
+ config.action_dispatch = ActiveSupport::OrderedOptions.new
12
+ config.action_dispatch.x_sendfile_header = nil
13
+ config.action_dispatch.ip_spoofing_check = true
14
+ config.action_dispatch.show_exceptions = :all
15
+ config.action_dispatch.tld_length = 1
16
+ config.action_dispatch.ignore_accept_header = false
17
+ config.action_dispatch.rescue_templates = {}
18
+ config.action_dispatch.rescue_responses = {}
19
+ config.action_dispatch.default_charset = nil
20
+ config.action_dispatch.rack_cache = false
21
+ config.action_dispatch.http_auth_salt = "http authentication"
22
+ config.action_dispatch.signed_cookie_salt = "signed cookie"
23
+ config.action_dispatch.encrypted_cookie_salt = "encrypted cookie"
24
+ config.action_dispatch.encrypted_signed_cookie_salt = "signed encrypted cookie"
25
+ config.action_dispatch.authenticated_encrypted_cookie_salt = "authenticated encrypted cookie"
26
+ config.action_dispatch.use_authenticated_cookie_encryption = false
27
+ config.action_dispatch.use_cookies_with_metadata = false
28
+ config.action_dispatch.perform_deep_munge = true
29
+ config.action_dispatch.request_id_header = ActionDispatch::Constants::X_REQUEST_ID
30
+ config.action_dispatch.log_rescued_responses = true
31
+ config.action_dispatch.debug_exception_log_level = :fatal
32
+ config.action_dispatch.strict_freshness = false
33
+
34
+ config.action_dispatch.default_headers = {
35
+ "X-Frame-Options" => "SAMEORIGIN",
36
+ "X-XSS-Protection" => "1; mode=block",
37
+ "X-Content-Type-Options" => "nosniff",
38
+ "X-Download-Options" => "noopen",
39
+ "X-Permitted-Cross-Domain-Policies" => "none",
40
+ "Referrer-Policy" => "strict-origin-when-cross-origin"
41
+ }
42
+
43
+ config.action_dispatch.cookies_rotations = ActiveSupport::Messages::RotationConfiguration.new
44
+
45
+ config.eager_load_namespaces << ActionDispatch
46
+
47
+ initializer "action_dispatch.deprecator", before: :load_environment_config do |app|
48
+ app.deprecators[:action_dispatch] = ActionDispatch.deprecator
49
+ end
50
+
51
+ initializer "action_dispatch.configure" do |app|
52
+ ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
53
+ ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
54
+
55
+ ActiveSupport.on_load(:action_dispatch_request) do
56
+ self.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
57
+ ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
58
+ end
59
+
60
+ ActiveSupport.on_load(:action_dispatch_response) do
61
+ self.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
62
+ self.default_headers = app.config.action_dispatch.default_headers
63
+ end
64
+
65
+ ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
66
+ ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)
67
+
68
+ config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
69
+ ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
70
+
71
+ ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
72
+
73
+ ActionDispatch::Http::Cache::Request.strict_freshness = app.config.action_dispatch.strict_freshness
74
+ ActionDispatch.test_app = app
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,283 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "rack/session/abstract/id"
6
+
7
+ module ActionDispatch
8
+ class Request
9
+ # Session is responsible for lazily loading the session from store.
10
+ class Session # :nodoc:
11
+ DisabledSessionError = Class.new(StandardError)
12
+ ENV_SESSION_KEY = Rack::RACK_SESSION # :nodoc:
13
+ ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS # :nodoc:
14
+
15
+ # Singleton object used to determine if an optional param wasn't specified.
16
+ Unspecified = Object.new
17
+
18
+ # Creates a session hash, merging the properties of the previous session if any.
19
+ def self.create(store, req, default_options)
20
+ session_was = find req
21
+ session = Request::Session.new(store, req)
22
+ session.merge! session_was if session_was
23
+
24
+ set(req, session)
25
+ Options.set(req, Request::Session::Options.new(store, default_options))
26
+ session
27
+ end
28
+
29
+ def self.disabled(req)
30
+ new(nil, req, enabled: false).tap do
31
+ Session::Options.set(req, Session::Options.new(nil, { id: nil }))
32
+ end
33
+ end
34
+
35
+ def self.find(req)
36
+ req.get_header ENV_SESSION_KEY
37
+ end
38
+
39
+ def self.set(req, session)
40
+ req.set_header ENV_SESSION_KEY, session
41
+ end
42
+
43
+ def self.delete(req)
44
+ req.delete_header ENV_SESSION_KEY
45
+ end
46
+
47
+ class Options # :nodoc:
48
+ def self.set(req, options)
49
+ req.set_header ENV_SESSION_OPTIONS_KEY, options
50
+ end
51
+
52
+ def self.find(req)
53
+ req.get_header ENV_SESSION_OPTIONS_KEY
54
+ end
55
+
56
+ def initialize(by, default_options)
57
+ @by = by
58
+ @delegate = default_options.dup
59
+ end
60
+
61
+ def [](key)
62
+ @delegate[key]
63
+ end
64
+
65
+ def id(req)
66
+ @delegate.fetch(:id) {
67
+ @by.send(:extract_session_id, req)
68
+ }
69
+ end
70
+
71
+ def []=(k, v); @delegate[k] = v; end
72
+ def to_hash; @delegate.dup; end
73
+ def values_at(*args); @delegate.values_at(*args); end
74
+ end
75
+
76
+ def initialize(by, req, enabled: true)
77
+ @by = by
78
+ @req = req
79
+ @delegate = {}
80
+ @loaded = false
81
+ @exists = nil # We haven't checked yet.
82
+ @enabled = enabled
83
+ @id_was = nil
84
+ @id_was_initialized = false
85
+ end
86
+
87
+ def id
88
+ options.id(@req)
89
+ end
90
+
91
+ def enabled?
92
+ @enabled
93
+ end
94
+
95
+ def options
96
+ Options.find @req
97
+ end
98
+
99
+ def destroy
100
+ clear
101
+
102
+ if enabled?
103
+ options = self.options || {}
104
+ @by.send(:delete_session, @req, options.id(@req), options)
105
+
106
+ # Load the new sid to be written with the response.
107
+ @loaded = false
108
+ load_for_write!
109
+ end
110
+ end
111
+
112
+ # Returns value of the key stored in the session or `nil` if the given key is
113
+ # not found in the session.
114
+ def [](key)
115
+ load_for_read!
116
+ key = key.to_s
117
+
118
+ if key == "session_id"
119
+ id&.public_id
120
+ else
121
+ @delegate[key]
122
+ end
123
+ end
124
+
125
+ # Returns the nested value specified by the sequence of keys, returning `nil` if
126
+ # any intermediate step is `nil`.
127
+ def dig(*keys)
128
+ load_for_read!
129
+ keys = keys.map.with_index { |key, i| i.zero? ? key.to_s : key }
130
+ @delegate.dig(*keys)
131
+ end
132
+
133
+ # Returns true if the session has the given key or false.
134
+ def has_key?(key)
135
+ load_for_read!
136
+ @delegate.key?(key.to_s)
137
+ end
138
+ alias :key? :has_key?
139
+ alias :include? :has_key?
140
+
141
+ # Returns keys of the session as Array.
142
+ def keys
143
+ load_for_read!
144
+ @delegate.keys
145
+ end
146
+
147
+ # Returns values of the session as Array.
148
+ def values
149
+ load_for_read!
150
+ @delegate.values
151
+ end
152
+
153
+ # Writes given value to given key of the session.
154
+ def []=(key, value)
155
+ load_for_write!
156
+ @delegate[key.to_s] = value
157
+ end
158
+
159
+ # Clears the session.
160
+ def clear
161
+ load_for_delete!
162
+ @delegate.clear
163
+ end
164
+
165
+ # Returns the session as Hash.
166
+ def to_hash
167
+ load_for_read!
168
+ @delegate.dup.delete_if { |_, v| v.nil? }
169
+ end
170
+ alias :to_h :to_hash
171
+
172
+ # Updates the session with given Hash.
173
+ #
174
+ # session.to_hash
175
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2"}
176
+ #
177
+ # session.update({ "foo" => "bar" })
178
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
179
+ #
180
+ # session.to_hash
181
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
182
+ def update(hash)
183
+ unless hash.respond_to?(:to_hash)
184
+ raise TypeError, "no implicit conversion of #{hash.class.name} into Hash"
185
+ end
186
+
187
+ load_for_write!
188
+ @delegate.update hash.to_hash.stringify_keys
189
+ end
190
+ alias :merge! :update
191
+
192
+ # Deletes given key from the session.
193
+ def delete(key)
194
+ load_for_delete!
195
+ @delegate.delete key.to_s
196
+ end
197
+
198
+ # Returns value of the given key from the session, or raises `KeyError` if can't
199
+ # find the given key and no default value is set. Returns default value if
200
+ # specified.
201
+ #
202
+ # session.fetch(:foo)
203
+ # # => KeyError: key not found: "foo"
204
+ #
205
+ # session.fetch(:foo, :bar)
206
+ # # => :bar
207
+ #
208
+ # session.fetch(:foo) do
209
+ # :bar
210
+ # end
211
+ # # => :bar
212
+ def fetch(key, default = Unspecified, &block)
213
+ load_for_read!
214
+ if default == Unspecified
215
+ @delegate.fetch(key.to_s, &block)
216
+ else
217
+ @delegate.fetch(key.to_s, default, &block)
218
+ end
219
+ end
220
+
221
+ def inspect
222
+ if loaded?
223
+ super
224
+ else
225
+ "#<#{self.class}:0x#{(object_id << 1).to_s(16)} not yet loaded>"
226
+ end
227
+ end
228
+
229
+ def exists?
230
+ return false unless enabled?
231
+ return @exists unless @exists.nil?
232
+ @exists = @by.send(:session_exists?, @req)
233
+ end
234
+
235
+ def loaded?
236
+ @loaded
237
+ end
238
+
239
+ def empty?
240
+ load_for_read!
241
+ @delegate.empty?
242
+ end
243
+
244
+ def each(&block)
245
+ to_hash.each(&block)
246
+ end
247
+
248
+ def id_was
249
+ load_for_read!
250
+ @id_was
251
+ end
252
+
253
+ private
254
+ def load_for_read!
255
+ load! if !loaded? && exists?
256
+ end
257
+
258
+ def load_for_write!
259
+ if enabled?
260
+ load! unless loaded?
261
+ else
262
+ raise DisabledSessionError, "Your application has sessions disabled. To write to the session you must first configure a session store"
263
+ end
264
+ end
265
+
266
+ def load_for_delete!
267
+ load! if enabled? && !loaded?
268
+ end
269
+
270
+ def load!
271
+ if enabled?
272
+ @id_was_initialized = true unless exists?
273
+ id, session = @by.load_session @req
274
+ options[:id] = id
275
+ @delegate.replace(session.stringify_keys)
276
+ @id_was = id unless @id_was_initialized
277
+ end
278
+ @id_was_initialized = true
279
+ @loaded = true
280
+ end
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "active_support/core_ext/hash/indifferent_access"
6
+
7
+ module ActionDispatch
8
+ class Request
9
+ class Utils # :nodoc:
10
+ mattr_accessor :perform_deep_munge, default: true
11
+
12
+ def self.each_param_value(params, &block)
13
+ case params
14
+ when Array
15
+ params.each { |element| each_param_value(element, &block) }
16
+ when Hash
17
+ params.each_value { |value| each_param_value(value, &block) }
18
+ when String
19
+ block.call params
20
+ end
21
+ end
22
+
23
+ def self.normalize_encode_params(params)
24
+ if perform_deep_munge
25
+ NoNilParamEncoder.normalize_encode_params params
26
+ else
27
+ ParamEncoder.normalize_encode_params params
28
+ end
29
+ end
30
+
31
+ def self.check_param_encoding(params)
32
+ case params
33
+ when Array
34
+ params.each { |element| check_param_encoding(element) }
35
+ when Hash
36
+ params.each_value { |value| check_param_encoding(value) }
37
+ when String
38
+ unless params.valid_encoding?
39
+ # Raise Rack::Utils::InvalidParameterError for consistency with Rack.
40
+ # ActionDispatch::Request#GET will re-raise as a BadRequest error.
41
+ raise Rack::Utils::InvalidParameterError, "Invalid encoding for parameter: #{params.scrub}"
42
+ end
43
+ end
44
+ end
45
+
46
+ def self.set_binary_encoding(request, params, controller, action)
47
+ CustomParamEncoder.encode(request, params, controller, action)
48
+ end
49
+
50
+ class ParamEncoder # :nodoc:
51
+ # Convert nested Hash to HashWithIndifferentAccess.
52
+ def self.normalize_encode_params(params)
53
+ case params
54
+ when Array
55
+ handle_array params
56
+ when Hash
57
+ if params.has_key?(:tempfile)
58
+ ActionDispatch::Http::UploadedFile.new(params)
59
+ else
60
+ hwia = ActiveSupport::HashWithIndifferentAccess.new
61
+ params.each_pair do |key, val|
62
+ hwia[key] = normalize_encode_params(val)
63
+ end
64
+ hwia
65
+ end
66
+ else
67
+ params
68
+ end
69
+ end
70
+
71
+ def self.handle_array(params)
72
+ params.map! { |el| normalize_encode_params(el) }
73
+ end
74
+ end
75
+
76
+ # Remove nils from the params hash.
77
+ class NoNilParamEncoder < ParamEncoder # :nodoc:
78
+ def self.handle_array(params)
79
+ list = super
80
+ list.compact!
81
+ list
82
+ end
83
+ end
84
+
85
+ class CustomParamEncoder # :nodoc:
86
+ def self.encode(request, params, controller, action)
87
+ return params unless controller && controller.valid_encoding? && encoding_template = action_encoding_template(request, controller, action)
88
+ params.except(:controller, :action).each do |key, value|
89
+ ActionDispatch::Request::Utils.each_param_value(value) do |param|
90
+ # If `param` is frozen, it comes from the router defaults
91
+ next if param.frozen?
92
+
93
+ if encoding_template[key.to_s]
94
+ param.force_encoding(encoding_template[key.to_s])
95
+ end
96
+ end
97
+ end
98
+ params
99
+ end
100
+
101
+ def self.action_encoding_template(request, controller, action) # :nodoc:
102
+ request.controller_class_for(controller).action_encoding_template(action)
103
+ rescue MissingController
104
+ nil
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ module ActionDispatch
6
+ module Routing
7
+ class Endpoint # :nodoc:
8
+ def dispatcher?; false; end
9
+ def redirect?; false; end
10
+ def matches?(req); true; end
11
+ def app; self; end
12
+ def rack_app; app; end
13
+
14
+ def engine?
15
+ rack_app.is_a?(Class) && rack_app < Rails::Engine
16
+ end
17
+ end
18
+ end
19
+ end