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,255 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The path plugin adds support for named paths. Using the +path+ class method, you can
7
+ # easily create <tt>*_path</tt> instance methods for each named path. Those instance
8
+ # methods can then be called if you need to get the path for a form action, link,
9
+ # redirect, or anything else.
10
+ #
11
+ # Additionally, you can call the +path+ class method with a class and a block, and it will register
12
+ # the class. You can then call the +path+ instance method with an instance of that class, and it will
13
+ # execute the block in the context of the route block scope with the arguments provided to path. You
14
+ # can call the +url+ instance method with the same arguments as the +path+ method to get the full URL.
15
+ #
16
+ # Example:
17
+ #
18
+ # plugin :path
19
+ # path :foo, '/foo'
20
+ # path :bar do |bar|
21
+ # "/bar/#{bar.id}"
22
+ # end
23
+ # path Baz do |baz, *paths|
24
+ # "/baz/#{baz.id}/#{paths.join('/')}"
25
+ # end
26
+ # path Quux do |quux, path|
27
+ # "/quux/#{quux.id}/#{path}"
28
+ # end
29
+ # path 'FooBar', class_name: true do |foobar|
30
+ # "/foobar/#{foobar.id}"
31
+ # end
32
+ #
33
+ # route do |r|
34
+ # r.post 'foo' do
35
+ # r.redirect foo_path # /foo
36
+ # end
37
+ #
38
+ # r.post 'bar' do
39
+ # bar_params = r.params['bar']
40
+ # if bar_params.is_a?(Hash)
41
+ # bar = Bar.create(bar_params)
42
+ # r.redirect bar_path(bar) # /bar/1
43
+ # end
44
+ # end
45
+ #
46
+ # r.post 'baz' do
47
+ # baz = Baz[1]
48
+ # r.redirect path(baz, 'c', 'd') # /baz/1/c/d
49
+ # end
50
+ #
51
+ # r.post 'quux' do
52
+ # quux = Quux[1]
53
+ # r.redirect url(quux, '/bar') # http://example.com/quux/1/bar
54
+ # end
55
+ # end
56
+ #
57
+ # The path class method accepts the following options when not called with a class:
58
+ #
59
+ # :add_script_name :: Prefix the path generated with SCRIPT_NAME. This defaults to the app's
60
+ # :add_script_name option.
61
+ # :name :: Provide a different name for the method, instead of using <tt>*_path</tt>.
62
+ # :relative :: Generate paths relative to the current request instead of absolute paths by prepending
63
+ # an appropriate prefix. This implies :add_script_name.
64
+ # :url :: Create a url method in addition to the path method, which will prefix the string generated
65
+ # with the appropriate scheme, host, and port. If true, creates a <tt>*_url</tt>
66
+ # method. If a Symbol or String, uses the value as the url method name.
67
+ # :url_only :: Do not create a path method, just a url method.
68
+ #
69
+ # Note that if :add_script_name, :relative, :url, or :url_only is used, the path method will also create a
70
+ # <tt>_*_path</tt> private method.
71
+ #
72
+ # If the path class method is passed a string or symbol as the first argument, and the second argument
73
+ # is a hash with the :class_name option passed, the symbol/string is treated as a class name.
74
+ # This enables the use of class-based paths without forcing autoloads for the related
75
+ # classes. If the plugin is not registering classes by name, this will use the symbol or
76
+ # string to find the related class.
77
+ module Path
78
+ DEFAULT_PORTS = {'http' => 80, 'https' => 443}.freeze
79
+
80
+ # Regexp for valid constant names, to prevent code execution.
81
+ VALID_CONSTANT_NAME_REGEXP = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.freeze
82
+
83
+ # Initialize the path classes when loading the plugin. Options:
84
+ # :by_name :: Register classes by name, which is friendlier when reloading code (defaults to
85
+ # true in development mode)
86
+ def self.configure(app, opts=OPTS)
87
+ app.instance_eval do
88
+ self.opts[:path_class_by_name] = opts.fetch(:by_name, ENV['RACK_ENV'] == 'development')
89
+ self.opts[:path_classes] ||= {}
90
+ self.opts[:path_class_methods] ||= {}
91
+ unless path_block(String)
92
+ path(String){|str| str}
93
+ end
94
+ end
95
+ end
96
+
97
+ module ClassMethods
98
+ # Hash of recognizes classes for path instance method. Keys are classes, values are procs.
99
+ def path_classes
100
+ opts[:path_classes]
101
+ end
102
+
103
+ # Freeze the path classes when freezing the app.
104
+ def freeze
105
+ path_classes.freeze
106
+ opts[:path_classes_methods].freeze
107
+ super
108
+ end
109
+
110
+ # Create a new instance method for the named path. See plugin module documentation for options.
111
+ def path(name, path=nil, opts=OPTS, &block)
112
+ if name.is_a?(Class) || (path.is_a?(Hash) && (class_name = path[:class_name]))
113
+ raise RodaError, "can't provide path when calling path with a class" if path && !class_name
114
+ raise RodaError, "can't provide options when calling path with a class" unless opts.empty?
115
+ raise RodaError, "must provide a block when calling path with a class" unless block
116
+ if self.opts[:path_class_by_name]
117
+ if class_name
118
+ name = name.to_s
119
+ else
120
+ name = name.name
121
+ end
122
+ elsif class_name
123
+ name = name.to_s
124
+ raise RodaError, "invalid class name passed when using class_name option" unless VALID_CONSTANT_NAME_REGEXP =~ name
125
+ name = Object.class_eval(name, __FILE__, __LINE__)
126
+ end
127
+ path_classes[name] = block
128
+ self.opts[:path_class_methods][name] = define_roda_method("path_#{name}", :any, &block)
129
+ return
130
+ end
131
+
132
+ if path.is_a?(Hash)
133
+ raise RodaError, "cannot provide two option hashses to Roda.path" unless opts.empty?
134
+ opts = path
135
+ path = nil
136
+ end
137
+
138
+ raise RodaError, "cannot provide both path and block to Roda.path" if path && block
139
+ raise RodaError, "must provide either path or block to Roda.path" unless path || block
140
+
141
+ if path
142
+ path = path.dup.freeze
143
+ block = lambda{path}
144
+ end
145
+
146
+ meth = opts[:name] || "#{name}_path"
147
+ url = opts[:url]
148
+ url_only = opts[:url_only]
149
+ relative = opts[:relative]
150
+ add_script_name = opts.fetch(:add_script_name, self.opts[:add_script_name])
151
+
152
+ if relative
153
+ if (url || url_only)
154
+ raise RodaError, "cannot provide :url or :url_only option if using :relative option"
155
+ end
156
+ add_script_name = true
157
+ plugin :relative_path
158
+ end
159
+
160
+ if add_script_name || url || url_only || relative
161
+ _meth = "_#{meth}"
162
+ define_method(_meth, &block)
163
+ private _meth
164
+ end
165
+
166
+ unless url_only
167
+ if relative
168
+ define_method(meth) do |*a, &blk|
169
+ # Allow calling private _method to get path
170
+ relative_path(request.script_name.to_s + send(_meth, *a, &blk))
171
+ end
172
+ # :nocov:
173
+ ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
174
+ # :nocov:
175
+ elsif add_script_name
176
+ define_method(meth) do |*a, &blk|
177
+ # Allow calling private _method to get path
178
+ request.script_name.to_s + send(_meth, *a, &blk)
179
+ end
180
+ # :nocov:
181
+ ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
182
+ # :nocov:
183
+ else
184
+ define_method(meth, &block)
185
+ end
186
+ end
187
+
188
+ if url || url_only
189
+ url_meth = if url.is_a?(String) || url.is_a?(Symbol)
190
+ url
191
+ else
192
+ "#{name}_url"
193
+ end
194
+
195
+ url_block = lambda do |*a, &blk|
196
+ # Allow calling private _method to get path
197
+ "#{_base_url}#{request.script_name if add_script_name}#{send(_meth, *a, &blk)}"
198
+ end
199
+
200
+ define_method(url_meth, &url_block)
201
+ # :nocov:
202
+ ruby2_keywords(url_meth) if respond_to?(:ruby2_keywords, true)
203
+ # :nocov:
204
+ end
205
+
206
+ nil
207
+ end
208
+
209
+ # Return the block related to the given class, or nil if there is no block.
210
+ def path_block(klass)
211
+ # RODA4: Remove
212
+ if opts[:path_class_by_name]
213
+ klass = klass.name
214
+ end
215
+ path_classes[klass]
216
+ end
217
+ end
218
+
219
+ module InstanceMethods
220
+ # Return a path based on the class of the object. The object passed must have
221
+ # had its class previously registered with the application. If the app's
222
+ # :add_script_name option is true, this prepends the SCRIPT_NAME to the path.
223
+ def path(obj, *args, &block)
224
+ app = self.class
225
+ opts = app.opts
226
+ klass = opts[:path_class_by_name] ? obj.class.name : obj.class
227
+ unless meth = opts[:path_class_methods][klass]
228
+ raise RodaError, "unrecognized object given to Roda#path: #{obj.inspect}"
229
+ end
230
+
231
+ path = send(meth, obj, *args, &block)
232
+ path = request.script_name.to_s + path if opts[:add_script_name]
233
+ path
234
+ end
235
+
236
+ # Similar to #path, but returns a complete URL.
237
+ def url(*args, &block)
238
+ "#{_base_url}#{path(*args, &block)}"
239
+ end
240
+
241
+ private
242
+
243
+ # The string to prepend to the path to make the path a URL.
244
+ def _base_url
245
+ r = @_request
246
+ scheme = r.scheme
247
+ port = r.port
248
+ "#{scheme}://#{r.host}#{":#{port}" unless DEFAULT_PORTS[scheme] == port}"
249
+ end
250
+ end
251
+ end
252
+
253
+ register_plugin(:path, Path)
254
+ end
255
+ end
@@ -0,0 +1,54 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The path_matchers plugin adds hash matchers that operate
7
+ # on the request's path.
8
+ #
9
+ # It adds a :prefix matcher for matching on the path's prefix,
10
+ # yielding the rest of the matched segment:
11
+ #
12
+ # r.on prefix: 'foo' do |suffix|
13
+ # # Matches '/foo-bar', yielding '-bar'
14
+ # # Does not match bar-foo
15
+ # end
16
+ #
17
+ # It adds a :suffix matcher for matching on the path's suffix,
18
+ # yielding the part of the segment before the suffix:
19
+ #
20
+ # r.on suffix: 'bar' do |prefix|
21
+ # # Matches '/foo-bar', yielding 'foo-'
22
+ # # Does not match bar-foo
23
+ # end
24
+ #
25
+ # It adds an :extension matcher for matching on the given file extension,
26
+ # yielding the part of the segment before the extension:
27
+ #
28
+ # r.on extension: 'bar' do |reset|
29
+ # # Matches '/foo.bar', yielding 'foo'
30
+ # # Does not match bar.foo
31
+ # end
32
+ module PathMatchers
33
+ module RequestMethods
34
+ # Match when the current segment ends with the given extension.
35
+ # request path end with the extension.
36
+ def match_extension(ext)
37
+ match_suffix(".#{ext}")
38
+ end
39
+
40
+ # Match when the current path segment starts with the given prefix.
41
+ def match_prefix(prefix)
42
+ consume(self.class.cached_matcher([:prefix, prefix]){/#{prefix}([^\\\/]+)/})
43
+ end
44
+
45
+ # Match when the current path segment ends with the given suffix.
46
+ def match_suffix(suffix)
47
+ consume(self.class.cached_matcher([:suffix, suffix]){/([^\\\/]+)#{suffix}/})
48
+ end
49
+ end
50
+ end
51
+
52
+ register_plugin(:path_matchers, PathMatchers)
53
+ end
54
+ end
@@ -0,0 +1,111 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The path_rewriter plugin allows you to rewrite the remaining path
7
+ # or the path info for requests. This is useful if you want to
8
+ # transparently treat some paths the same as other paths.
9
+ #
10
+ # By default, +rewrite_path+ will rewrite just the remaining path. So
11
+ # only routing in the current Roda app will be affected. This is useful
12
+ # if you have other code in your app that uses PATH_INFO and needs to
13
+ # see the original PATH_INFO (for example, when using relative links).
14
+ #
15
+ # rewrite_path '/a', '/b'
16
+ # # PATH_INFO '/a' => remaining_path '/b'
17
+ # # PATH_INFO '/a/c' => remaining_path '/b/c'
18
+ #
19
+ # In some cases, you may want to override PATH_INFO for the rewritten
20
+ # paths, such as when you are passing the request to another Rack app.
21
+ # For those cases, you can use the <tt>path_info: true</tt> option to
22
+ # +rewrite_path+.
23
+ #
24
+ # rewrite_path '/a', '/b', path_info: true
25
+ # # PATH_INFO '/a' => PATH_INFO '/b'
26
+ # # PATH_INFO '/a/c' => PATH_INFO '/b/c'
27
+ #
28
+ # If you pass a string to +rewrite_path+, it will rewrite all paths starting
29
+ # with that string. You can provide a regexp if you want more complete control,
30
+ # such as only matching exact paths.
31
+ #
32
+ # rewrite_path /\A\/a\z/, '/b'
33
+ # # PATH_INFO '/a' => remaining_path '/b'
34
+ # # PATH_INFO '/a/c' => remaining_path '/a/c', no change
35
+ #
36
+ # Patterns can be rewritten dynamically by providing a block accepting a MatchData
37
+ # object and evaluating to the replacement.
38
+ #
39
+ # rewrite_path(/\A\/a\/(\w+)/){|match| "/a/#{match[1].capitalize}"}
40
+ # # PATH_INFO '/a/moo' => remaining_path '/a/Moo'
41
+ # rewrite_path(/\A\/a\/(\w+)/, path_info: true){|match| "/a/#{match[1].capitalize}"}
42
+ # # PATH_INFO '/a/moo' => PATH_INFO '/a/Moo'
43
+ #
44
+ # All path rewrites are applied in order, so if a path is rewritten by one rewrite,
45
+ # it can be rewritten again by a later rewrite. Note that PATH_INFO rewrites are
46
+ # processed before remaining_path rewrites.
47
+ module PathRewriter
48
+ def self.configure(app)
49
+ app.instance_exec do
50
+ app.opts[:remaining_path_rewrites] ||= []
51
+ app.opts[:path_info_rewrites] ||= []
52
+ end
53
+ end
54
+
55
+ module ClassMethods
56
+ # Freeze the path rewrite metadata.
57
+ def freeze
58
+ opts[:remaining_path_rewrites].freeze
59
+ opts[:path_info_rewrites].freeze
60
+ super
61
+ end
62
+
63
+ # Record a path rewrite from path +was+ to path +is+. Options:
64
+ # :path_info :: Modify PATH_INFO, not just remaining path.
65
+ def rewrite_path(was, is = nil, opts=OPTS, &block)
66
+ if is.is_a? Hash
67
+ raise RodaError, "cannot provide two hashes to rewrite_path" unless opts.empty?
68
+ opts = is
69
+ is = nil
70
+ end
71
+
72
+ if block
73
+ raise RodaError, "cannot provide both block and string replacement to rewrite_path" if is
74
+ is = block
75
+ end
76
+
77
+ was = /\A#{Regexp.escape(was)}/ unless was.is_a?(Regexp)
78
+ array = @opts[opts[:path_info] ? :path_info_rewrites : :remaining_path_rewrites]
79
+ array << [was, is.dup.freeze].freeze
80
+ end
81
+ end
82
+
83
+ module RequestMethods
84
+ # Rewrite remaining_path and/or PATH_INFO based on the path rewrites.
85
+ def initialize(scope, env)
86
+ path_info = env['PATH_INFO']
87
+
88
+ rewrite_path(scope.class.opts[:path_info_rewrites], path_info)
89
+ super
90
+ remaining_path = @remaining_path = @remaining_path.dup
91
+ rewrite_path(scope.class.opts[:remaining_path_rewrites], remaining_path)
92
+ end
93
+
94
+ private
95
+
96
+ # Rewrite the given path using the given replacements.
97
+ def rewrite_path(replacements, path)
98
+ replacements.each do |was, is|
99
+ if is.is_a?(Proc)
100
+ path.sub!(was){is.call($~)}
101
+ else
102
+ path.sub!(was, is)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ register_plugin(:path_rewriter, PathRewriter)
110
+ end
111
+ end