ultra-max-sys 0.0.1

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 ultra-max-sys might be problematic. Click here for more details.

Files changed (163) hide show
  1. checksums.yaml +7 -0
  2. data/roda-3.106.0/MIT-LICENSE +21 -0
  3. data/roda-3.106.0/lib/roda/cache.rb +42 -0
  4. data/roda-3.106.0/lib/roda/plugins/Integer_matcher_max.rb +55 -0
  5. data/roda-3.106.0/lib/roda/plugins/_after_hook.rb +11 -0
  6. data/roda-3.106.0/lib/roda/plugins/_base64.rb +34 -0
  7. data/roda-3.106.0/lib/roda/plugins/_before_hook.rb +41 -0
  8. data/roda-3.106.0/lib/roda/plugins/_optimized_matching.rb +227 -0
  9. data/roda-3.106.0/lib/roda/plugins/_symbol_class_matchers.rb +108 -0
  10. data/roda-3.106.0/lib/roda/plugins/_symbol_regexp_matchers.rb +24 -0
  11. data/roda-3.106.0/lib/roda/plugins/additional_render_engines.rb +61 -0
  12. data/roda-3.106.0/lib/roda/plugins/additional_view_directories.rb +66 -0
  13. data/roda-3.106.0/lib/roda/plugins/all_verbs.rb +50 -0
  14. data/roda-3.106.0/lib/roda/plugins/assets.rb +902 -0
  15. data/roda-3.106.0/lib/roda/plugins/assets_preloading.rb +89 -0
  16. data/roda-3.106.0/lib/roda/plugins/assume_ssl.rb +28 -0
  17. data/roda-3.106.0/lib/roda/plugins/autoload_hash_branches.rb +79 -0
  18. data/roda-3.106.0/lib/roda/plugins/autoload_named_routes.rb +65 -0
  19. data/roda-3.106.0/lib/roda/plugins/backtracking_array.rb +88 -0
  20. data/roda-3.106.0/lib/roda/plugins/bearer_token.rb +28 -0
  21. data/roda-3.106.0/lib/roda/plugins/branch_locals.rb +76 -0
  22. data/roda-3.106.0/lib/roda/plugins/break.rb +43 -0
  23. data/roda-3.106.0/lib/roda/plugins/caching.rb +206 -0
  24. data/roda-3.106.0/lib/roda/plugins/capture_erb.rb +94 -0
  25. data/roda-3.106.0/lib/roda/plugins/chunked.rb +333 -0
  26. data/roda-3.106.0/lib/roda/plugins/class_level_routing.rb +111 -0
  27. data/roda-3.106.0/lib/roda/plugins/class_matchers.rb +155 -0
  28. data/roda-3.106.0/lib/roda/plugins/common_logger.rb +82 -0
  29. data/roda-3.106.0/lib/roda/plugins/conditional_sessions.rb +67 -0
  30. data/roda-3.106.0/lib/roda/plugins/content_for.rb +105 -0
  31. data/roda-3.106.0/lib/roda/plugins/content_security_policy.rb +333 -0
  32. data/roda-3.106.0/lib/roda/plugins/cookie_flags.rb +157 -0
  33. data/roda-3.106.0/lib/roda/plugins/cookies.rb +51 -0
  34. data/roda-3.106.0/lib/roda/plugins/csrf.rb +81 -0
  35. data/roda-3.106.0/lib/roda/plugins/custom_block_results.rb +85 -0
  36. data/roda-3.106.0/lib/roda/plugins/custom_matchers.rb +89 -0
  37. data/roda-3.106.0/lib/roda/plugins/default_headers.rb +64 -0
  38. data/roda-3.106.0/lib/roda/plugins/default_status.rb +35 -0
  39. data/roda-3.106.0/lib/roda/plugins/delay_build.rb +18 -0
  40. data/roda-3.106.0/lib/roda/plugins/delegate.rb +77 -0
  41. data/roda-3.106.0/lib/roda/plugins/delete_empty_headers.rb +36 -0
  42. data/roda-3.106.0/lib/roda/plugins/direct_call.rb +38 -0
  43. data/roda-3.106.0/lib/roda/plugins/disallow_file_uploads.rb +38 -0
  44. data/roda-3.106.0/lib/roda/plugins/drop_body.rb +43 -0
  45. data/roda-3.106.0/lib/roda/plugins/each_part.rb +87 -0
  46. data/roda-3.106.0/lib/roda/plugins/early_hints.rb +25 -0
  47. data/roda-3.106.0/lib/roda/plugins/empty_root.rb +49 -0
  48. data/roda-3.106.0/lib/roda/plugins/environments.rb +79 -0
  49. data/roda-3.106.0/lib/roda/plugins/erb_h.rb +43 -0
  50. data/roda-3.106.0/lib/roda/plugins/error_email.rb +152 -0
  51. data/roda-3.106.0/lib/roda/plugins/error_handler.rb +133 -0
  52. data/roda-3.106.0/lib/roda/plugins/error_mail.rb +149 -0
  53. data/roda-3.106.0/lib/roda/plugins/exception_page.rb +445 -0
  54. data/roda-3.106.0/lib/roda/plugins/filter_common_logger.rb +46 -0
  55. data/roda-3.106.0/lib/roda/plugins/flash.rb +119 -0
  56. data/roda-3.106.0/lib/roda/plugins/h.rb +59 -0
  57. data/roda-3.106.0/lib/roda/plugins/halt.rb +108 -0
  58. data/roda-3.106.0/lib/roda/plugins/hash_branch_view_subdir.rb +76 -0
  59. data/roda-3.106.0/lib/roda/plugins/hash_branches.rb +145 -0
  60. data/roda-3.106.0/lib/roda/plugins/hash_matcher.rb +39 -0
  61. data/roda-3.106.0/lib/roda/plugins/hash_paths.rb +128 -0
  62. data/roda-3.106.0/lib/roda/plugins/hash_public.rb +125 -0
  63. data/roda-3.106.0/lib/roda/plugins/hash_public_cache.rb +91 -0
  64. data/roda-3.106.0/lib/roda/plugins/hash_routes.rb +304 -0
  65. data/roda-3.106.0/lib/roda/plugins/head.rb +99 -0
  66. data/roda-3.106.0/lib/roda/plugins/header_matchers.rb +88 -0
  67. data/roda-3.106.0/lib/roda/plugins/heartbeat.rb +41 -0
  68. data/roda-3.106.0/lib/roda/plugins/hmac_paths.rb +413 -0
  69. data/roda-3.106.0/lib/roda/plugins/hooks.rb +92 -0
  70. data/roda-3.106.0/lib/roda/plugins/host_authorization.rb +155 -0
  71. data/roda-3.106.0/lib/roda/plugins/host_routing.rb +194 -0
  72. data/roda-3.106.0/lib/roda/plugins/hsts.rb +35 -0
  73. data/roda-3.106.0/lib/roda/plugins/indifferent_params.rb +126 -0
  74. data/roda-3.106.0/lib/roda/plugins/inject_erb.rb +33 -0
  75. data/roda-3.106.0/lib/roda/plugins/invalid_request_body.rb +107 -0
  76. data/roda-3.106.0/lib/roda/plugins/ip_from_header.rb +34 -0
  77. data/roda-3.106.0/lib/roda/plugins/json.rb +119 -0
  78. data/roda-3.106.0/lib/roda/plugins/json_parser.rb +107 -0
  79. data/roda-3.106.0/lib/roda/plugins/link_to.rb +83 -0
  80. data/roda-3.106.0/lib/roda/plugins/mail_processor.rb +629 -0
  81. data/roda-3.106.0/lib/roda/plugins/mailer.rb +285 -0
  82. data/roda-3.106.0/lib/roda/plugins/map_matcher.rb +48 -0
  83. data/roda-3.106.0/lib/roda/plugins/match_affix.rb +64 -0
  84. data/roda-3.106.0/lib/roda/plugins/match_hook.rb +34 -0
  85. data/roda-3.106.0/lib/roda/plugins/match_hook_args.rb +93 -0
  86. data/roda-3.106.0/lib/roda/plugins/middleware.rb +225 -0
  87. data/roda-3.106.0/lib/roda/plugins/middleware_stack.rb +101 -0
  88. data/roda-3.106.0/lib/roda/plugins/module_include.rb +96 -0
  89. data/roda-3.106.0/lib/roda/plugins/multi_public.rb +95 -0
  90. data/roda-3.106.0/lib/roda/plugins/multi_route.rb +156 -0
  91. data/roda-3.106.0/lib/roda/plugins/multi_run.rb +144 -0
  92. data/roda-3.106.0/lib/roda/plugins/multi_view.rb +83 -0
  93. data/roda-3.106.0/lib/roda/plugins/multibyte_string_matcher.rb +57 -0
  94. data/roda-3.106.0/lib/roda/plugins/named_routes.rb +167 -0
  95. data/roda-3.106.0/lib/roda/plugins/named_templates.rb +102 -0
  96. data/roda-3.106.0/lib/roda/plugins/not_allowed.rb +151 -0
  97. data/roda-3.106.0/lib/roda/plugins/not_found.rb +55 -0
  98. data/roda-3.106.0/lib/roda/plugins/optimized_segment_matchers.rb +53 -0
  99. data/roda-3.106.0/lib/roda/plugins/optimized_string_matchers.rb +50 -0
  100. data/roda-3.106.0/lib/roda/plugins/padrino_render.rb +42 -0
  101. data/roda-3.106.0/lib/roda/plugins/param_matchers.rb +83 -0
  102. data/roda-3.106.0/lib/roda/plugins/params_capturing.rb +118 -0
  103. data/roda-3.106.0/lib/roda/plugins/part.rb +76 -0
  104. data/roda-3.106.0/lib/roda/plugins/partials.rb +74 -0
  105. data/roda-3.106.0/lib/roda/plugins/pass.rb +47 -0
  106. data/roda-3.106.0/lib/roda/plugins/path.rb +255 -0
  107. data/roda-3.106.0/lib/roda/plugins/path_matchers.rb +54 -0
  108. data/roda-3.106.0/lib/roda/plugins/path_rewriter.rb +111 -0
  109. data/roda-3.106.0/lib/roda/plugins/permissions_policy.rb +340 -0
  110. data/roda-3.106.0/lib/roda/plugins/placeholder_string_matchers.rb +48 -0
  111. data/roda-3.106.0/lib/roda/plugins/plain_hash_response_headers.rb +32 -0
  112. data/roda-3.106.0/lib/roda/plugins/precompile_templates.rb +156 -0
  113. data/roda-3.106.0/lib/roda/plugins/public.rb +182 -0
  114. data/roda-3.106.0/lib/roda/plugins/r.rb +35 -0
  115. data/roda-3.106.0/lib/roda/plugins/recheck_precompiled_assets.rb +107 -0
  116. data/roda-3.106.0/lib/roda/plugins/redirect_http_to_https.rb +99 -0
  117. data/roda-3.106.0/lib/roda/plugins/redirect_path.rb +59 -0
  118. data/roda-3.106.0/lib/roda/plugins/relative_path.rb +76 -0
  119. data/roda-3.106.0/lib/roda/plugins/render.rb +998 -0
  120. data/roda-3.106.0/lib/roda/plugins/render_coverage.rb +105 -0
  121. data/roda-3.106.0/lib/roda/plugins/render_each.rb +224 -0
  122. data/roda-3.106.0/lib/roda/plugins/render_locals.rb +102 -0
  123. data/roda-3.106.0/lib/roda/plugins/request_aref.rb +77 -0
  124. data/roda-3.106.0/lib/roda/plugins/request_headers.rb +83 -0
  125. data/roda-3.106.0/lib/roda/plugins/response_attachment.rb +94 -0
  126. data/roda-3.106.0/lib/roda/plugins/response_content_type.rb +79 -0
  127. data/roda-3.106.0/lib/roda/plugins/response_request.rb +36 -0
  128. data/roda-3.106.0/lib/roda/plugins/route_block_args.rb +50 -0
  129. data/roda-3.106.0/lib/roda/plugins/route_csrf.rb +388 -0
  130. data/roda-3.106.0/lib/roda/plugins/run_append_slash.rb +51 -0
  131. data/roda-3.106.0/lib/roda/plugins/run_handler.rb +51 -0
  132. data/roda-3.106.0/lib/roda/plugins/run_require_slash.rb +46 -0
  133. data/roda-3.106.0/lib/roda/plugins/sec_fetch_site_csrf.rb +131 -0
  134. data/roda-3.106.0/lib/roda/plugins/send_file.rb +127 -0
  135. data/roda-3.106.0/lib/roda/plugins/sessions.rb +537 -0
  136. data/roda-3.106.0/lib/roda/plugins/shape_friendly.rb +232 -0
  137. data/roda-3.106.0/lib/roda/plugins/shared_vars.rb +86 -0
  138. data/roda-3.106.0/lib/roda/plugins/sinatra_helpers.rb +444 -0
  139. data/roda-3.106.0/lib/roda/plugins/slash_path_empty.rb +26 -0
  140. data/roda-3.106.0/lib/roda/plugins/static.rb +42 -0
  141. data/roda-3.106.0/lib/roda/plugins/static_routing.rb +89 -0
  142. data/roda-3.106.0/lib/roda/plugins/status_303.rb +34 -0
  143. data/roda-3.106.0/lib/roda/plugins/status_handler.rb +86 -0
  144. data/roda-3.106.0/lib/roda/plugins/streaming.rb +170 -0
  145. data/roda-3.106.0/lib/roda/plugins/strip_path_prefix.rb +33 -0
  146. data/roda-3.106.0/lib/roda/plugins/symbol_matchers.rb +188 -0
  147. data/roda-3.106.0/lib/roda/plugins/symbol_status.rb +32 -0
  148. data/roda-3.106.0/lib/roda/plugins/symbol_views.rb +37 -0
  149. data/roda-3.106.0/lib/roda/plugins/timestamp_public.rb +78 -0
  150. data/roda-3.106.0/lib/roda/plugins/type_routing.rb +217 -0
  151. data/roda-3.106.0/lib/roda/plugins/typecast_params.rb +1185 -0
  152. data/roda-3.106.0/lib/roda/plugins/typecast_params_sized_integers.rb +108 -0
  153. data/roda-3.106.0/lib/roda/plugins/unescape_path.rb +41 -0
  154. data/roda-3.106.0/lib/roda/plugins/view_options.rb +203 -0
  155. data/roda-3.106.0/lib/roda/plugins/view_subdir_leading_slash.rb +49 -0
  156. data/roda-3.106.0/lib/roda/plugins.rb +68 -0
  157. data/roda-3.106.0/lib/roda/request.rb +722 -0
  158. data/roda-3.106.0/lib/roda/response.rb +221 -0
  159. data/roda-3.106.0/lib/roda/session_middleware.rb +184 -0
  160. data/roda-3.106.0/lib/roda/version.rb +18 -0
  161. data/roda-3.106.0/lib/roda.rb +741 -0
  162. data/ultra-max-sys.gemspec +12 -0
  163. metadata +202 -0
@@ -0,0 +1,194 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The host_routing plugin adds support for more routing requests based on
7
+ # the requested host. It also adds predicate methods for checking
8
+ # whether a request was requested with the given host.
9
+ #
10
+ # When loading the plugin, you pass a block, which is used for configuring
11
+ # the plugin. For example, if you want to treat requests to api.example.com
12
+ # or api2.example.com as api requests, and treat other requests as www
13
+ # requests, you could use:
14
+ #
15
+ # plugin :host_routing do |hosts|
16
+ # hosts.to :api, "api.example.com", "api2.example.com"
17
+ # hosts.default :www
18
+ # end
19
+ #
20
+ # With this configuration, in your routing tree, you can call the +r.api+ and
21
+ # +r.www+ methods for dispatching to routing blocks only for those types of
22
+ # requests:
23
+ #
24
+ # route do |r|
25
+ # r.api do
26
+ # # requests to api.example.com or api2.example.com
27
+ # end
28
+ #
29
+ # r.www do
30
+ # # requests to other domains
31
+ # end
32
+ # end
33
+ #
34
+ # In addition to the routing methods, predicate methods are also added to the
35
+ # request object:
36
+ #
37
+ # route do |r|
38
+ # "#{r.api?}-#{r.www?}"
39
+ # end
40
+ # # Requests to api.example.com or api2.example.com return "true-false"
41
+ # # Other requests return "false-true"
42
+ #
43
+ # If the +:scope_predicates+ plugin option is given, predicate methods are also
44
+ # created in route block scope:
45
+ #
46
+ # plugin :host_routing, scope_predicates: true do |hosts|
47
+ # hosts.to :api, "api.example.com"
48
+ # hosts.default :www
49
+ # end
50
+ #
51
+ # route do |r|
52
+ # "#{api?}-#{www?}"
53
+ # end
54
+ #
55
+ # To handle hosts that match a certain format (such as all subdomains),
56
+ # where the specific host names are not known up front, you can provide a block
57
+ # when calling +hosts.default+. This block is passed the host name, or an empty
58
+ # string if no host name is provided, and is evaluated in route block scope.
59
+ # When using this support, you should also call +hosts.register+
60
+ # to register host types that could be returned by the block. For example, to
61
+ # handle api subdomains differently:
62
+ #
63
+ # plugin :host_routing do |hosts|
64
+ # hosts.to :api, "api.example.com"
65
+ # hosts.register :api_sub
66
+ # hosts.default :www do |host|
67
+ # :api_sub if host.end_with?(".api.example.com")
68
+ # end
69
+ # end
70
+ #
71
+ # This plugin uses the host method on the request to get the hostname (this method
72
+ # is defined by Rack).
73
+ module HostRouting
74
+ REQUEST_INSTANCE_VARIABLES = [:@_host_routing_host].freeze
75
+
76
+ # Setup the host routing support. The block yields an object used to
77
+ # configure the plugin. Options:
78
+ #
79
+ # :scope_predicates :: Setup predicate methods in route block scope
80
+ # in addition to request scope.
81
+ def self.configure(app, opts=OPTS, &block)
82
+ hosts, host_hash, default_block, default_host = DSL.new.process(&block)
83
+ app.opts[:host_routing_hash] = host_hash
84
+ app.opts[:host_routing_default_host] = default_host
85
+
86
+ app.send(:define_method, :_host_routing_default, &default_block) if default_block
87
+
88
+ app::RodaRequest.class_exec do
89
+ hosts.each do |host|
90
+ host_sym = host.to_sym
91
+ define_method(host_sym){|&blk| always(&blk) if _host_routing_host == host}
92
+ alias_method host_sym, host_sym
93
+
94
+ meth = :"#{host}?"
95
+ define_method(meth){_host_routing_host == host}
96
+ alias_method meth, meth
97
+ end
98
+ end
99
+
100
+ if opts[:scope_predicates]
101
+ app.class_exec do
102
+ hosts.each do |host|
103
+ meth = :"#{host}?"
104
+ define_method(meth){@_request.send(meth)}
105
+ alias_method meth, meth
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ class DSL
112
+ def initialize
113
+ @hosts = []
114
+ @host_hash = {}
115
+ @default_host = nil
116
+ @default_block = nil
117
+ end
118
+
119
+ # Run the DSL for the given block.
120
+ def process(&block)
121
+ instance_exec(self, &block)
122
+
123
+ if !@default_host
124
+ raise RodaError, "must call default method inside host_routing plugin block to set default host"
125
+ end
126
+
127
+ @hosts.concat(@host_hash.values)
128
+ @hosts << @default_host
129
+ @hosts.uniq!
130
+ [@hosts.freeze, @host_hash.freeze, @default_block, @default_host].freeze
131
+ end
132
+
133
+ # Register hosts that can be returned. This is only needed if
134
+ # calling register with a block, where the block can return
135
+ # a value that doesn't match a host given to +to+ or +default+.
136
+ def register(*hosts)
137
+ @hosts = hosts
138
+ end
139
+
140
+ # Treat all given hostnames as routing to the give host.
141
+ def to(host, *hostnames)
142
+ hostnames.each do |hostname|
143
+ @host_hash[hostname] = host
144
+ end
145
+ end
146
+
147
+ # Register the default hostname. If a block is provided, it is
148
+ # called with the host if there is no match for one of the hostnames
149
+ # provided to +to+. If the block returns nil/false, the hostname
150
+ # given to this method is used.
151
+ def default(hostname, &block)
152
+ @default_host = hostname
153
+ @default_block = block
154
+ end
155
+ end
156
+ private_constant :DSL
157
+
158
+ module InstanceMethods
159
+ # Handle case where plugin is used without providing a block to
160
+ # +hosts.default+. This returns nil, ensuring that the hostname
161
+ # provided to +hosts.default+ will be used.
162
+ def _host_routing_default(_)
163
+ nil
164
+ end
165
+ end
166
+
167
+ module RequestMethods
168
+ private
169
+
170
+ # Cache the host to use in the host routing support, so the processing
171
+ # is only done once per request.
172
+ def _host_routing_host
173
+ @_host_routing_host ||= _get_host_routing_host
174
+ end
175
+
176
+ # Determine the host to use for the host routing support. Tries the
177
+ # following, in order:
178
+ #
179
+ # * An exact match for a hostname given in +hosts.to+
180
+ # * The return value of the +hosts.default+ block, if given
181
+ # * The default value provided in the +hosts.default+ call
182
+ def _get_host_routing_host
183
+ host = self.host || ""
184
+
185
+ roda_class.opts[:host_routing_hash][host] ||
186
+ scope._host_routing_default(host) ||
187
+ roda_class.opts[:host_routing_default_host]
188
+ end
189
+ end
190
+ end
191
+
192
+ register_plugin(:host_routing, HostRouting)
193
+ end
194
+ end
@@ -0,0 +1,35 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The hsts plugin allows for easily configuring an appropriate
7
+ # Strict-Transport-Security response header for the application:
8
+ #
9
+ # plugin :hsts
10
+ # # Strict-Transport-Security: max-age=63072000; includeSubDomains
11
+ #
12
+ # plugin :hsts, preload: true
13
+ # # Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
14
+ #
15
+ # plugin :hsts, max_age: 31536000, subdomains: false
16
+ # # Strict-Transport-Security: max-age=31536000
17
+ module Hsts
18
+ # Ensure default_headers plugin is loaded first
19
+ def self.load_dependencies(app, opts=OPTS)
20
+ app.plugin :default_headers
21
+ end
22
+
23
+ # Configure the Strict-Transport-Security header. Options:
24
+ # :max_age :: Set max-age in seconds (default is 63072000, two years)
25
+ # :preload :: Set preload, so the domain can be included in HSTS preload lists
26
+ # :subdomains :: Set to false to not set includeSubDomains. By default,
27
+ # includeSubDomains is set to enforce HTTPS for subdomains.
28
+ def self.configure(app, opts=OPTS)
29
+ app.plugin :default_headers, RodaResponseHeaders::STRICT_TRANSPORT_SECURITY => "max-age=#{opts[:max_age]||63072000}#{'; includeSubDomains' unless opts[:subdomains] == false}#{'; preload' if opts[:preload]}".freeze
30
+ end
31
+ end
32
+
33
+ register_plugin(:hsts, Hsts)
34
+ end
35
+ end
@@ -0,0 +1,126 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The indifferent_params plugin adds a +params+ instance
7
+ # method which offers indifferent access to the request
8
+ # params, allowing you to use symbols to lookup values in
9
+ # a hash where the keys are strings. Note that while this
10
+ # allows for an easier transition from some other ruby frameworks,
11
+ # it is a bad idea in general as it makes it more difficult to
12
+ # separate external data from internal data, and doesn't handle
13
+ # any typecasting of the data. Consider using the typecast_params
14
+ # plugin instead of this plugin for accessing parameters.
15
+ #
16
+ # Example:
17
+ #
18
+ # plugin :indifferent_params
19
+ #
20
+ # route do |r|
21
+ # params[:foo]
22
+ # end
23
+ #
24
+ # The exact behavior depends on the version of Rack in use.
25
+ # If you are using Rack 2, this plugin uses rack's API
26
+ # to set the query parser for the request to use indifferent
27
+ # access. Rack 1 doesn't support indifferent access to
28
+ # params, so if you are using Rack 1, this plugin will make
29
+ # a deep copy of the request params hash, where each level
30
+ # uses indifferent access. On Rack 1, The params hash is
31
+ # initialized lazily, so you only pay the penalty of
32
+ # copying the request params if you call the +params+ method.
33
+ #
34
+ # Note that there is a rack-indifferent gem that
35
+ # monkey patches rack to always use indifferent params. If
36
+ # you are using Rack 1, it is recommended to use
37
+ # rack-indifferent instead of this plugin, as it is faster
38
+ # and has some other minor advantages, though
39
+ # it affects all rack applications instead of just the Roda app that
40
+ # you load the plugin into.
41
+ module IndifferentParams
42
+ SCOPE_INSTANCE_VARIABLES = [:@_params].freeze
43
+
44
+ INDIFFERENT_PROC = lambda{|h,k| h[k.to_s] if k.is_a?(Symbol)}
45
+
46
+ if Rack.release > '2'
47
+ require 'rack/query_parser'
48
+
49
+ class QueryParser < Rack::QueryParser
50
+ # Work around for invalid optimization in rack
51
+ def parse_nested_query(qs, d=nil)
52
+ return make_params.to_params_hash if qs.nil? || qs.empty?
53
+ super
54
+ end
55
+
56
+ class Params < Rack::QueryParser::Params
57
+ if Rack.release >= '3'
58
+ if Params < Hash
59
+ def initialize
60
+ super(&INDIFFERENT_PROC)
61
+ end
62
+ else
63
+ def initialize
64
+ @size = 0
65
+ @params = Hash.new(&INDIFFERENT_PROC)
66
+ end
67
+ end
68
+ else
69
+ def initialize(limit = Rack::Utils.key_space_limit)
70
+ @limit = limit
71
+ @size = 0
72
+ @params = Hash.new(&INDIFFERENT_PROC)
73
+ end
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ module RequestMethods
80
+ query_parser = Rack.release >= '3' ? QueryParser.new(QueryParser::Params, 32) : QueryParser.new(QueryParser::Params, 65536, 32)
81
+ QUERY_PARSER = Rack::Utils.default_query_parser = query_parser
82
+
83
+ private
84
+
85
+ def query_parser
86
+ QUERY_PARSER
87
+ end
88
+ end
89
+
90
+ module InstanceMethods
91
+ def params
92
+ @_request.params
93
+ end
94
+ end
95
+ else
96
+ module InstanceMethods
97
+ # A copy of the request params that will automatically
98
+ # convert symbols to strings.
99
+ def params
100
+ @_params ||= indifferent_params(@_request.params)
101
+ end
102
+
103
+ private
104
+
105
+ # Recursively process the request params and convert
106
+ # hashes to support indifferent access, leaving
107
+ # other values alone.
108
+ def indifferent_params(params)
109
+ case params
110
+ when Hash
111
+ hash = Hash.new(&INDIFFERENT_PROC)
112
+ params.each{|k, v| hash[k] = indifferent_params(v)}
113
+ hash
114
+ when Array
115
+ params.map{|x| indifferent_params(x)}
116
+ else
117
+ params
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ register_plugin(:indifferent_params, IndifferentParams)
125
+ end
126
+ end
@@ -0,0 +1,33 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The inject_erb plugin allows you to inject content directly
7
+ # into the template output:
8
+ #
9
+ # <% inject_erb("Some HTML Here") %>
10
+ #
11
+ # This will inject <tt>Some HTML Here</tt> into the template output,
12
+ # even though the tag being used is <tt><%</tt> and not <tt><%=</tt>.
13
+ #
14
+ # This method can be used inside methods, such as to wrap calls to
15
+ # methods that accept template blocks, to inject code before and after
16
+ # the template blocks.
17
+ module InjectERB
18
+ def self.load_dependencies(app)
19
+ app.plugin :render
20
+ end
21
+
22
+ module InstanceMethods
23
+ # Inject into the template output for the template currently being
24
+ # rendered.
25
+ def inject_erb(value)
26
+ instance_variable_get(render_opts[:template_opts][:outvar]) << value.to_s
27
+ end
28
+ end
29
+ end
30
+
31
+ register_plugin(:inject_erb, InjectERB)
32
+ end
33
+ end
@@ -0,0 +1,107 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The invalid_request_body plugin allows for custom handling of invalid request
7
+ # bodies. Roda uses Rack for parsing request bodies, so by default, any
8
+ # invalid request bodies would result in Rack raising an exception, and the
9
+ # exception could change for different reasons the request body is invalid.
10
+ # This plugin overrides RodaRequest#POST (which parses parameters from request
11
+ # bodies), and if parsing raises an exception, it allows for custom behavior.
12
+ #
13
+ # If you want to treat an invalid request body as the submission of no parameters,
14
+ # you can use the :empty_hash argument when loading the plugin:
15
+ #
16
+ # plugin :invalid_request_body, :empty_hash
17
+ #
18
+ # If you want to return a empty 400 (Bad Request) response if an invalid request
19
+ # body is submitted, you can use the :empty_400 argument when loading the plugin:
20
+ #
21
+ # plugin :invalid_request_body, :empty_400
22
+ #
23
+ # If you want to raise a Roda::RodaPlugins::InvalidRequestBody::Error exception
24
+ # if an invalid request body is submitted (which makes it easier to handle these
25
+ # exceptions when using the error_handler plugin), you can use the :raise argument
26
+ # when loading the plugin:
27
+ #
28
+ # plugin :invalid_request_body, :raise
29
+ #
30
+ # For custom behavior, you can pass a block when loading the plugin. The block
31
+ # is called with the exception Rack raised when parsing the body. The block will
32
+ # be used to define a method in the application's RodaRequest class. It can either
33
+ # return a hash of parameters, or you can raise a different exception, or you
34
+ # can halt processing and return a response:
35
+ #
36
+ # plugin :invalid_request_body do |exception|
37
+ # # To treat the exception raised as a submitted parameter
38
+ # {body_error: exception}
39
+ # end
40
+ module InvalidRequestBody
41
+ # Exception class raised for invalid request bodies.
42
+ Error = Class.new(RodaError)
43
+
44
+ # Set the action to use (:empty_400, :empty_hash, :raise) for invalid request bodies,
45
+ # or use a block for custom behavior.
46
+ def self.configure(app, action=nil, &block)
47
+ if action
48
+ if block
49
+ raise RodaError, "cannot provide both block and action when loading invalid_request_body plugin"
50
+ end
51
+
52
+ method = :"handle_invalid_request_body_#{action}"
53
+ unless RequestMethods.private_method_defined?(method)
54
+ raise RodaError, "invalid invalid_request_body action provided: #{action}"
55
+ end
56
+
57
+ app::RodaRequest.send(:alias_method, :handle_invalid_request_body, method)
58
+ elsif block
59
+ app::RodaRequest.class_eval do
60
+ define_method(:handle_invalid_request_body, &block)
61
+ alias handle_invalid_request_body handle_invalid_request_body
62
+ end
63
+ else
64
+ raise RodaError, "must provide block or action when loading invalid_request_body plugin"
65
+ end
66
+
67
+ app::RodaRequest.send(:private, :handle_invalid_request_body)
68
+ end
69
+
70
+ module RequestMethods
71
+ # Handle invalid request bodies as configured if the default behavior
72
+ # raises an exception.
73
+ def POST
74
+ super
75
+ rescue => e
76
+ handle_invalid_request_body(e)
77
+ end
78
+
79
+ private
80
+
81
+ # Return an empty 400 HTTP response for invalid request bodies.
82
+ def handle_invalid_request_body_empty_400(e)
83
+ response.status = 400
84
+ headers = response.headers
85
+ headers.clear
86
+ headers[RodaResponseHeaders::CONTENT_TYPE] = 'text/html'
87
+ headers[RodaResponseHeaders::CONTENT_LENGTH] ='0'
88
+ throw :halt, response.finish_with_body([])
89
+ end
90
+
91
+ # Treat invalid request bodies by using an empty hash as the
92
+ # POST params.
93
+ def handle_invalid_request_body_empty_hash(e)
94
+ {}
95
+ end
96
+
97
+ # Raise a specific error for all invalid request bodies,
98
+ # to allow for easy rescuing using the error_handler plugin.
99
+ def handle_invalid_request_body_raise(e)
100
+ raise Error, e.message
101
+ end
102
+ end
103
+ end
104
+
105
+ register_plugin(:invalid_request_body, InvalidRequestBody)
106
+ end
107
+ end
@@ -0,0 +1,34 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The ip_from_header plugin allows for overriding +request.ip+ to return
7
+ # the value contained in a specific header. This is useful when the
8
+ # application is behind a proxy that sets a specific header, especially
9
+ # when the proxy does not use a fixed IP address range. Example showing
10
+ # usage with Cloudflare:
11
+ #
12
+ # plugin :ip_from_header, "CF-Connecting-IP"
13
+ #
14
+ # This plugin assumes that if the header is set, it contains a valid IP
15
+ # address, it does not check the format of the header value, just as
16
+ # <tt>Rack::Request#ip</tt> does not check the IP address it returns is
17
+ # actually valid.
18
+ module IPFromHeader
19
+ def self.configure(app, header)
20
+ app.opts[:ip_from_header_env_key] = "HTTP_#{header.upcase.tr('-', '_')}".freeze
21
+ end
22
+
23
+ module RequestMethods
24
+ # Return the IP address continained in the configured header, if present.
25
+ # Fallback to the default behavior if not present.
26
+ def ip
27
+ @env[roda_class.opts[:ip_from_header_env_key]] || super
28
+ end
29
+ end
30
+ end
31
+
32
+ register_plugin(:ip_from_header, IPFromHeader)
33
+ end
34
+ end
@@ -0,0 +1,119 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'json'
4
+
5
+ class Roda
6
+ module RodaPlugins
7
+ # The json plugin allows match blocks to return
8
+ # arrays or hashes, and have those arrays or hashes be
9
+ # converted to json which is used as the response body.
10
+ # It also sets the response content type to application/json.
11
+ # So you can take code like:
12
+ #
13
+ # r.root do
14
+ # response['Content-Type'] = 'application/json'
15
+ # [1, 2, 3].to_json
16
+ # end
17
+ # r.is "foo" do
18
+ # response['Content-Type'] = 'application/json'
19
+ # {'a'=>'b'}.to_json
20
+ # end
21
+ #
22
+ # and DRY it up:
23
+ #
24
+ # plugin :json
25
+ # r.root do
26
+ # [1, 2, 3]
27
+ # end
28
+ # r.is "foo" do
29
+ # {'a'=>'b'}
30
+ # end
31
+ #
32
+ # By default, only arrays and hashes are handled, but you
33
+ # can specifically set the allowed classes to json by adding
34
+ # using the :classes option when loading the plugin:
35
+ #
36
+ # plugin :json, classes: [Array, Hash, Sequel::Model]
37
+ #
38
+ # By default objects are serialized with +to_json+, but you
39
+ # can pass in a custom serializer, which can be any object
40
+ # that responds to +call(object)+.
41
+ #
42
+ # plugin :json, serializer: proc{|o| o.to_json(root: true)}
43
+ #
44
+ # If you need the request information during serialization, such
45
+ # as HTTP headers or query parameters, you can pass in the
46
+ # +:include_request+ option, which will pass in the request
47
+ # object as the second argument when calling the serializer.
48
+ #
49
+ # plugin :json, include_request: true, serializer: proc{|o, request| ...}
50
+ #
51
+ # The default content-type is 'application/json', but you can change that
52
+ # using the +:content_type+ option:
53
+ #
54
+ # plugin :json, content_type: 'application/xml'
55
+ #
56
+ # This plugin depends on the custom_block_results plugin, and therefore does
57
+ # not support treating String, FalseClass, or NilClass values as JSON.
58
+ module Json
59
+ def self.load_dependencies(app, opts=OPTS)
60
+ app.plugin :custom_block_results
61
+ end
62
+
63
+ # Set the classes to automatically convert to JSON, and the serializer to use.
64
+ def self.configure(app, opts=OPTS)
65
+ classes = opts[:classes] || [Array, Hash]
66
+ app.opts[:json_result_classes] ||= []
67
+ app.opts[:json_result_classes] += classes
68
+ classes = app.opts[:json_result_classes]
69
+ classes.uniq!
70
+ classes.freeze
71
+ classes.each do |klass|
72
+ app.opts[:custom_block_results][klass] = :handle_json_block_result
73
+ end
74
+
75
+ app.opts[:json_result_serializer] = opts[:serializer] || app.opts[:json_result_serializer] || app.opts[:json_serializer] || :to_json.to_proc
76
+
77
+ app.opts[:json_result_include_request] = opts[:include_request] if opts.has_key?(:include_request)
78
+
79
+ app.opts[:json_result_content_type] = opts[:content_type] || 'application/json'.freeze
80
+ end
81
+
82
+ module ClassMethods
83
+ # The classes that should be automatically converted to json
84
+ def json_result_classes
85
+ # RODA4: remove, only used by previous implementation.
86
+ opts[:json_result_classes]
87
+ end
88
+ end
89
+
90
+ module InstanceMethods
91
+ # Handle a result for one of the registered JSON result classes
92
+ # by converting the result to JSON.
93
+ def handle_json_block_result(result)
94
+ @_response[RodaResponseHeaders::CONTENT_TYPE] ||= opts[:json_result_content_type]
95
+ @_request.send(:convert_to_json, result)
96
+ end
97
+ end
98
+
99
+ module RequestMethods
100
+ private
101
+
102
+ # Convert the given object to JSON. Uses to_json by default,
103
+ # but can use a custom serializer passed to the plugin.
104
+ def convert_to_json(result)
105
+ opts = roda_class.opts
106
+ serializer = opts[:json_result_serializer]
107
+
108
+ if opts[:json_result_include_request]
109
+ serializer.call(result, self)
110
+ else
111
+ serializer.call(result)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ register_plugin(:json, Json)
118
+ end
119
+ end