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,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ module ActionDispatch
6
+ module Http
7
+ module Parameters
8
+ extend ActiveSupport::Concern
9
+
10
+ PARAMETERS_KEY = "action_dispatch.request.path_parameters"
11
+
12
+ DEFAULT_PARSERS = {
13
+ Mime[:json].symbol => -> (raw_post) {
14
+ data = ActiveSupport::JSON.decode(raw_post)
15
+ data.is_a?(Hash) ? data : { _json: data }
16
+ }
17
+ }
18
+
19
+ # Raised when raw data from the request cannot be parsed by the parser defined
20
+ # for request's content MIME type.
21
+ class ParseError < StandardError
22
+ def initialize(message = $!.message)
23
+ super(message)
24
+ end
25
+ end
26
+
27
+ included do
28
+ class << self
29
+ # Returns the parameter parsers.
30
+ attr_reader :parameter_parsers
31
+ end
32
+
33
+ self.parameter_parsers = DEFAULT_PARSERS
34
+ end
35
+
36
+ module ClassMethods
37
+ # Configure the parameter parser for a given MIME type.
38
+ #
39
+ # It accepts a hash where the key is the symbol of the MIME type and the value
40
+ # is a proc.
41
+ #
42
+ # original_parsers = ActionDispatch::Request.parameter_parsers
43
+ # xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} }
44
+ # new_parsers = original_parsers.merge(xml: xml_parser)
45
+ # ActionDispatch::Request.parameter_parsers = new_parsers
46
+ def parameter_parsers=(parsers)
47
+ @parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
48
+ end
49
+ end
50
+
51
+ # Returns both GET and POST parameters in a single hash.
52
+ def parameters
53
+ params = get_header("action_dispatch.request.parameters")
54
+ return params if params
55
+
56
+ params = begin
57
+ request_parameters.merge(query_parameters)
58
+ rescue EOFError
59
+ query_parameters.dup
60
+ end
61
+ params.merge!(path_parameters)
62
+ set_header("action_dispatch.request.parameters", params)
63
+ params
64
+ end
65
+ alias :params :parameters
66
+
67
+ def path_parameters=(parameters) # :nodoc:
68
+ delete_header("action_dispatch.request.parameters")
69
+
70
+ parameters = Request::Utils.set_binary_encoding(self, parameters, parameters[:controller], parameters[:action])
71
+ # If any of the path parameters has an invalid encoding then raise since it's
72
+ # likely to trigger errors further on.
73
+ Request::Utils.check_param_encoding(parameters)
74
+
75
+ set_header PARAMETERS_KEY, parameters
76
+ rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
77
+ raise ActionController::BadRequest.new("Invalid path parameters: #{e.message}")
78
+ end
79
+
80
+ # Returns a hash with the parameters used to form the path of the request.
81
+ # Returned hash keys are symbols:
82
+ #
83
+ # { action: "my_action", controller: "my_controller" }
84
+ def path_parameters
85
+ get_header(PARAMETERS_KEY) || set_header(PARAMETERS_KEY, {})
86
+ end
87
+
88
+ private
89
+ def parse_formatted_parameters(parsers)
90
+ return yield if content_length.zero? || content_mime_type.nil?
91
+
92
+ strategy = parsers.fetch(content_mime_type.symbol) { return yield }
93
+
94
+ begin
95
+ strategy.call(raw_post)
96
+ rescue # JSON or Ruby code block errors.
97
+ log_parse_error_once
98
+ raise ParseError, "Error occurred while parsing request parameters"
99
+ end
100
+ end
101
+
102
+ def log_parse_error_once
103
+ @parse_error_logged ||= begin
104
+ parse_logger = logger || ActiveSupport::Logger.new($stderr)
105
+ parse_logger.debug <<~MSG.chomp
106
+ Error occurred while parsing request parameters.
107
+ Contents:
108
+
109
+ #{raw_post}
110
+ MSG
111
+ end
112
+ end
113
+
114
+ def params_parsers
115
+ ActionDispatch::Request.parameter_parsers
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ require "active_support/core_ext/object/deep_dup"
6
+
7
+ module ActionDispatch # :nodoc:
8
+ # # Action Dispatch PermissionsPolicy
9
+ #
10
+ # Configures the HTTP
11
+ # [Feature-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy)
12
+ # response header to specify which browser features the current
13
+ # document and its iframes can use.
14
+ #
15
+ # Example global policy:
16
+ #
17
+ # Rails.application.config.permissions_policy do |policy|
18
+ # policy.camera :none
19
+ # policy.gyroscope :none
20
+ # policy.microphone :none
21
+ # policy.usb :none
22
+ # policy.fullscreen :self
23
+ # policy.payment :self, "https://secure.example.com"
24
+ # end
25
+ #
26
+ # The Feature-Policy header has been renamed to Permissions-Policy. The
27
+ # Permissions-Policy requires a different implementation and isn't yet supported
28
+ # by all browsers. To avoid having to rename this middleware in the future we
29
+ # use the new name for the middleware but keep the old header name and
30
+ # implementation for now.
31
+ class PermissionsPolicy
32
+ class Middleware
33
+ def initialize(app)
34
+ @app = app
35
+ end
36
+
37
+ def call(env)
38
+ _, headers, _ = response = @app.call(env)
39
+
40
+ return response if policy_present?(headers)
41
+
42
+ request = ActionDispatch::Request.new(env)
43
+
44
+ if policy = request.permissions_policy
45
+ headers[ActionDispatch::Constants::FEATURE_POLICY] = policy.build(request.controller_instance)
46
+ end
47
+
48
+ if policy_empty?(policy)
49
+ headers.delete(ActionDispatch::Constants::FEATURE_POLICY)
50
+ end
51
+
52
+ response
53
+ end
54
+
55
+ private
56
+ def policy_present?(headers)
57
+ headers[ActionDispatch::Constants::FEATURE_POLICY]
58
+ end
59
+
60
+ def policy_empty?(policy)
61
+ policy&.directives&.empty?
62
+ end
63
+ end
64
+
65
+ module Request
66
+ POLICY = "action_dispatch.permissions_policy"
67
+
68
+ def permissions_policy
69
+ get_header(POLICY)
70
+ end
71
+
72
+ def permissions_policy=(policy)
73
+ set_header(POLICY, policy)
74
+ end
75
+ end
76
+
77
+ MAPPINGS = {
78
+ self: "'self'",
79
+ none: "'none'",
80
+ }.freeze
81
+
82
+ # List of available permissions can be found at
83
+ # https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md#policy-controlled-features
84
+ DIRECTIVES = {
85
+ accelerometer: "accelerometer",
86
+ ambient_light_sensor: "ambient-light-sensor",
87
+ autoplay: "autoplay",
88
+ camera: "camera",
89
+ display_capture: "display-capture",
90
+ encrypted_media: "encrypted-media",
91
+ fullscreen: "fullscreen",
92
+ geolocation: "geolocation",
93
+ gyroscope: "gyroscope",
94
+ hid: "hid",
95
+ idle_detection: "idle-detection",
96
+ keyboard_map: "keyboard-map",
97
+ magnetometer: "magnetometer",
98
+ microphone: "microphone",
99
+ midi: "midi",
100
+ payment: "payment",
101
+ picture_in_picture: "picture-in-picture",
102
+ screen_wake_lock: "screen-wake-lock",
103
+ serial: "serial",
104
+ sync_xhr: "sync-xhr",
105
+ usb: "usb",
106
+ web_share: "web-share",
107
+ }.freeze
108
+
109
+ private_constant :MAPPINGS, :DIRECTIVES
110
+
111
+ attr_reader :directives
112
+
113
+ def initialize
114
+ @directives = {}
115
+ yield self if block_given?
116
+ end
117
+
118
+ def initialize_copy(other)
119
+ @directives = other.directives.deep_dup
120
+ end
121
+
122
+ DIRECTIVES.each do |name, directive|
123
+ define_method(name) do |*sources|
124
+ if sources.first
125
+ @directives[directive] = apply_mappings(sources)
126
+ else
127
+ @directives.delete(directive)
128
+ end
129
+ end
130
+ end
131
+
132
+ def build(context = nil)
133
+ build_directives(context).compact.join("; ")
134
+ end
135
+
136
+ private
137
+ def apply_mappings(sources)
138
+ sources.map do |source|
139
+ case source
140
+ when Symbol
141
+ apply_mapping(source)
142
+ when String, Proc
143
+ source
144
+ else
145
+ raise ArgumentError, "Invalid HTTP permissions policy source: #{source.inspect}"
146
+ end
147
+ end
148
+ end
149
+
150
+ def apply_mapping(source)
151
+ MAPPINGS.fetch(source) do
152
+ raise ArgumentError, "Unknown HTTP permissions policy source mapping: #{source.inspect}"
153
+ end
154
+ end
155
+
156
+ def build_directives(context)
157
+ @directives.map do |directive, sources|
158
+ if sources.is_a?(Array)
159
+ "#{directive} #{build_directive(sources, context).join(' ')}"
160
+ elsif sources
161
+ directive
162
+ else
163
+ nil
164
+ end
165
+ end
166
+ end
167
+
168
+ def build_directive(sources, context)
169
+ sources.map { |source| resolve_source(source, context) }
170
+ end
171
+
172
+ def resolve_source(source, context)
173
+ case source
174
+ when String
175
+ source
176
+ when Symbol
177
+ source.to_s
178
+ when Proc
179
+ if context.nil?
180
+ raise RuntimeError, "Missing context for the dynamic permissions policy source: #{source.inspect}"
181
+ else
182
+ context.instance_exec(&source)
183
+ end
184
+ else
185
+ raise RuntimeError, "Unexpected permissions policy source: #{source.inspect}"
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :enddoc:
4
+
5
+ # :markup: markdown
6
+
7
+ require "rack/cache"
8
+ require "rack/cache/context"
9
+ require "active_support/cache"
10
+
11
+ module ActionDispatch
12
+ class RailsMetaStore < Rack::Cache::MetaStore
13
+ def self.resolve(uri)
14
+ new
15
+ end
16
+
17
+ def initialize(store = Rails.cache)
18
+ @store = store
19
+ end
20
+
21
+ def read(key)
22
+ if data = @store.read(key)
23
+ Marshal.load(data)
24
+ else
25
+ []
26
+ end
27
+ end
28
+
29
+ def write(key, value)
30
+ @store.write(key, Marshal.dump(value))
31
+ end
32
+
33
+ ::Rack::Cache::MetaStore::RAILS = self
34
+ end
35
+
36
+ class RailsEntityStore < Rack::Cache::EntityStore
37
+ def self.resolve(uri)
38
+ new
39
+ end
40
+
41
+ def initialize(store = Rails.cache)
42
+ @store = store
43
+ end
44
+
45
+ def exist?(key)
46
+ @store.exist?(key)
47
+ end
48
+
49
+ def open(key)
50
+ @store.read(key)
51
+ end
52
+
53
+ def read(key)
54
+ body = open(key)
55
+ body.join if body
56
+ end
57
+
58
+ def write(body)
59
+ buf = []
60
+ key, size = slurp(body) { |part| buf << part }
61
+ @store.write(key, buf)
62
+ [key, size]
63
+ end
64
+
65
+ ::Rack::Cache::EntityStore::RAILS = self
66
+ end
67
+ end