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.
- checksums.yaml +7 -0
- data/roda-3.106.0/MIT-LICENSE +21 -0
- data/roda-3.106.0/lib/roda/cache.rb +42 -0
- data/roda-3.106.0/lib/roda/plugins/Integer_matcher_max.rb +55 -0
- data/roda-3.106.0/lib/roda/plugins/_after_hook.rb +11 -0
- data/roda-3.106.0/lib/roda/plugins/_base64.rb +34 -0
- data/roda-3.106.0/lib/roda/plugins/_before_hook.rb +41 -0
- data/roda-3.106.0/lib/roda/plugins/_optimized_matching.rb +227 -0
- data/roda-3.106.0/lib/roda/plugins/_symbol_class_matchers.rb +108 -0
- data/roda-3.106.0/lib/roda/plugins/_symbol_regexp_matchers.rb +24 -0
- data/roda-3.106.0/lib/roda/plugins/additional_render_engines.rb +61 -0
- data/roda-3.106.0/lib/roda/plugins/additional_view_directories.rb +66 -0
- data/roda-3.106.0/lib/roda/plugins/all_verbs.rb +50 -0
- data/roda-3.106.0/lib/roda/plugins/assets.rb +902 -0
- data/roda-3.106.0/lib/roda/plugins/assets_preloading.rb +89 -0
- data/roda-3.106.0/lib/roda/plugins/assume_ssl.rb +28 -0
- data/roda-3.106.0/lib/roda/plugins/autoload_hash_branches.rb +79 -0
- data/roda-3.106.0/lib/roda/plugins/autoload_named_routes.rb +65 -0
- data/roda-3.106.0/lib/roda/plugins/backtracking_array.rb +88 -0
- data/roda-3.106.0/lib/roda/plugins/bearer_token.rb +28 -0
- data/roda-3.106.0/lib/roda/plugins/branch_locals.rb +76 -0
- data/roda-3.106.0/lib/roda/plugins/break.rb +43 -0
- data/roda-3.106.0/lib/roda/plugins/caching.rb +206 -0
- data/roda-3.106.0/lib/roda/plugins/capture_erb.rb +94 -0
- data/roda-3.106.0/lib/roda/plugins/chunked.rb +333 -0
- data/roda-3.106.0/lib/roda/plugins/class_level_routing.rb +111 -0
- data/roda-3.106.0/lib/roda/plugins/class_matchers.rb +155 -0
- data/roda-3.106.0/lib/roda/plugins/common_logger.rb +82 -0
- data/roda-3.106.0/lib/roda/plugins/conditional_sessions.rb +67 -0
- data/roda-3.106.0/lib/roda/plugins/content_for.rb +105 -0
- data/roda-3.106.0/lib/roda/plugins/content_security_policy.rb +333 -0
- data/roda-3.106.0/lib/roda/plugins/cookie_flags.rb +157 -0
- data/roda-3.106.0/lib/roda/plugins/cookies.rb +51 -0
- data/roda-3.106.0/lib/roda/plugins/csrf.rb +81 -0
- data/roda-3.106.0/lib/roda/plugins/custom_block_results.rb +85 -0
- data/roda-3.106.0/lib/roda/plugins/custom_matchers.rb +89 -0
- data/roda-3.106.0/lib/roda/plugins/default_headers.rb +64 -0
- data/roda-3.106.0/lib/roda/plugins/default_status.rb +35 -0
- data/roda-3.106.0/lib/roda/plugins/delay_build.rb +18 -0
- data/roda-3.106.0/lib/roda/plugins/delegate.rb +77 -0
- data/roda-3.106.0/lib/roda/plugins/delete_empty_headers.rb +36 -0
- data/roda-3.106.0/lib/roda/plugins/direct_call.rb +38 -0
- data/roda-3.106.0/lib/roda/plugins/disallow_file_uploads.rb +38 -0
- data/roda-3.106.0/lib/roda/plugins/drop_body.rb +43 -0
- data/roda-3.106.0/lib/roda/plugins/each_part.rb +87 -0
- data/roda-3.106.0/lib/roda/plugins/early_hints.rb +25 -0
- data/roda-3.106.0/lib/roda/plugins/empty_root.rb +49 -0
- data/roda-3.106.0/lib/roda/plugins/environments.rb +79 -0
- data/roda-3.106.0/lib/roda/plugins/erb_h.rb +43 -0
- data/roda-3.106.0/lib/roda/plugins/error_email.rb +152 -0
- data/roda-3.106.0/lib/roda/plugins/error_handler.rb +133 -0
- data/roda-3.106.0/lib/roda/plugins/error_mail.rb +149 -0
- data/roda-3.106.0/lib/roda/plugins/exception_page.rb +445 -0
- data/roda-3.106.0/lib/roda/plugins/filter_common_logger.rb +46 -0
- data/roda-3.106.0/lib/roda/plugins/flash.rb +119 -0
- data/roda-3.106.0/lib/roda/plugins/h.rb +59 -0
- data/roda-3.106.0/lib/roda/plugins/halt.rb +108 -0
- data/roda-3.106.0/lib/roda/plugins/hash_branch_view_subdir.rb +76 -0
- data/roda-3.106.0/lib/roda/plugins/hash_branches.rb +145 -0
- data/roda-3.106.0/lib/roda/plugins/hash_matcher.rb +39 -0
- data/roda-3.106.0/lib/roda/plugins/hash_paths.rb +128 -0
- data/roda-3.106.0/lib/roda/plugins/hash_public.rb +125 -0
- data/roda-3.106.0/lib/roda/plugins/hash_public_cache.rb +91 -0
- data/roda-3.106.0/lib/roda/plugins/hash_routes.rb +304 -0
- data/roda-3.106.0/lib/roda/plugins/head.rb +99 -0
- data/roda-3.106.0/lib/roda/plugins/header_matchers.rb +88 -0
- data/roda-3.106.0/lib/roda/plugins/heartbeat.rb +41 -0
- data/roda-3.106.0/lib/roda/plugins/hmac_paths.rb +413 -0
- data/roda-3.106.0/lib/roda/plugins/hooks.rb +92 -0
- data/roda-3.106.0/lib/roda/plugins/host_authorization.rb +155 -0
- data/roda-3.106.0/lib/roda/plugins/host_routing.rb +194 -0
- data/roda-3.106.0/lib/roda/plugins/hsts.rb +35 -0
- data/roda-3.106.0/lib/roda/plugins/indifferent_params.rb +126 -0
- data/roda-3.106.0/lib/roda/plugins/inject_erb.rb +33 -0
- data/roda-3.106.0/lib/roda/plugins/invalid_request_body.rb +107 -0
- data/roda-3.106.0/lib/roda/plugins/ip_from_header.rb +34 -0
- data/roda-3.106.0/lib/roda/plugins/json.rb +119 -0
- data/roda-3.106.0/lib/roda/plugins/json_parser.rb +107 -0
- data/roda-3.106.0/lib/roda/plugins/link_to.rb +83 -0
- data/roda-3.106.0/lib/roda/plugins/mail_processor.rb +629 -0
- data/roda-3.106.0/lib/roda/plugins/mailer.rb +285 -0
- data/roda-3.106.0/lib/roda/plugins/map_matcher.rb +48 -0
- data/roda-3.106.0/lib/roda/plugins/match_affix.rb +64 -0
- data/roda-3.106.0/lib/roda/plugins/match_hook.rb +34 -0
- data/roda-3.106.0/lib/roda/plugins/match_hook_args.rb +93 -0
- data/roda-3.106.0/lib/roda/plugins/middleware.rb +225 -0
- data/roda-3.106.0/lib/roda/plugins/middleware_stack.rb +101 -0
- data/roda-3.106.0/lib/roda/plugins/module_include.rb +96 -0
- data/roda-3.106.0/lib/roda/plugins/multi_public.rb +95 -0
- data/roda-3.106.0/lib/roda/plugins/multi_route.rb +156 -0
- data/roda-3.106.0/lib/roda/plugins/multi_run.rb +144 -0
- data/roda-3.106.0/lib/roda/plugins/multi_view.rb +83 -0
- data/roda-3.106.0/lib/roda/plugins/multibyte_string_matcher.rb +57 -0
- data/roda-3.106.0/lib/roda/plugins/named_routes.rb +167 -0
- data/roda-3.106.0/lib/roda/plugins/named_templates.rb +102 -0
- data/roda-3.106.0/lib/roda/plugins/not_allowed.rb +151 -0
- data/roda-3.106.0/lib/roda/plugins/not_found.rb +55 -0
- data/roda-3.106.0/lib/roda/plugins/optimized_segment_matchers.rb +53 -0
- data/roda-3.106.0/lib/roda/plugins/optimized_string_matchers.rb +50 -0
- data/roda-3.106.0/lib/roda/plugins/padrino_render.rb +42 -0
- data/roda-3.106.0/lib/roda/plugins/param_matchers.rb +83 -0
- data/roda-3.106.0/lib/roda/plugins/params_capturing.rb +118 -0
- data/roda-3.106.0/lib/roda/plugins/part.rb +76 -0
- data/roda-3.106.0/lib/roda/plugins/partials.rb +74 -0
- data/roda-3.106.0/lib/roda/plugins/pass.rb +47 -0
- data/roda-3.106.0/lib/roda/plugins/path.rb +255 -0
- data/roda-3.106.0/lib/roda/plugins/path_matchers.rb +54 -0
- data/roda-3.106.0/lib/roda/plugins/path_rewriter.rb +111 -0
- data/roda-3.106.0/lib/roda/plugins/permissions_policy.rb +340 -0
- data/roda-3.106.0/lib/roda/plugins/placeholder_string_matchers.rb +48 -0
- data/roda-3.106.0/lib/roda/plugins/plain_hash_response_headers.rb +32 -0
- data/roda-3.106.0/lib/roda/plugins/precompile_templates.rb +156 -0
- data/roda-3.106.0/lib/roda/plugins/public.rb +182 -0
- data/roda-3.106.0/lib/roda/plugins/r.rb +35 -0
- data/roda-3.106.0/lib/roda/plugins/recheck_precompiled_assets.rb +107 -0
- data/roda-3.106.0/lib/roda/plugins/redirect_http_to_https.rb +99 -0
- data/roda-3.106.0/lib/roda/plugins/redirect_path.rb +59 -0
- data/roda-3.106.0/lib/roda/plugins/relative_path.rb +76 -0
- data/roda-3.106.0/lib/roda/plugins/render.rb +998 -0
- data/roda-3.106.0/lib/roda/plugins/render_coverage.rb +105 -0
- data/roda-3.106.0/lib/roda/plugins/render_each.rb +224 -0
- data/roda-3.106.0/lib/roda/plugins/render_locals.rb +102 -0
- data/roda-3.106.0/lib/roda/plugins/request_aref.rb +77 -0
- data/roda-3.106.0/lib/roda/plugins/request_headers.rb +83 -0
- data/roda-3.106.0/lib/roda/plugins/response_attachment.rb +94 -0
- data/roda-3.106.0/lib/roda/plugins/response_content_type.rb +79 -0
- data/roda-3.106.0/lib/roda/plugins/response_request.rb +36 -0
- data/roda-3.106.0/lib/roda/plugins/route_block_args.rb +50 -0
- data/roda-3.106.0/lib/roda/plugins/route_csrf.rb +388 -0
- data/roda-3.106.0/lib/roda/plugins/run_append_slash.rb +51 -0
- data/roda-3.106.0/lib/roda/plugins/run_handler.rb +51 -0
- data/roda-3.106.0/lib/roda/plugins/run_require_slash.rb +46 -0
- data/roda-3.106.0/lib/roda/plugins/sec_fetch_site_csrf.rb +131 -0
- data/roda-3.106.0/lib/roda/plugins/send_file.rb +127 -0
- data/roda-3.106.0/lib/roda/plugins/sessions.rb +537 -0
- data/roda-3.106.0/lib/roda/plugins/shape_friendly.rb +232 -0
- data/roda-3.106.0/lib/roda/plugins/shared_vars.rb +86 -0
- data/roda-3.106.0/lib/roda/plugins/sinatra_helpers.rb +444 -0
- data/roda-3.106.0/lib/roda/plugins/slash_path_empty.rb +26 -0
- data/roda-3.106.0/lib/roda/plugins/static.rb +42 -0
- data/roda-3.106.0/lib/roda/plugins/static_routing.rb +89 -0
- data/roda-3.106.0/lib/roda/plugins/status_303.rb +34 -0
- data/roda-3.106.0/lib/roda/plugins/status_handler.rb +86 -0
- data/roda-3.106.0/lib/roda/plugins/streaming.rb +170 -0
- data/roda-3.106.0/lib/roda/plugins/strip_path_prefix.rb +33 -0
- data/roda-3.106.0/lib/roda/plugins/symbol_matchers.rb +188 -0
- data/roda-3.106.0/lib/roda/plugins/symbol_status.rb +32 -0
- data/roda-3.106.0/lib/roda/plugins/symbol_views.rb +37 -0
- data/roda-3.106.0/lib/roda/plugins/timestamp_public.rb +78 -0
- data/roda-3.106.0/lib/roda/plugins/type_routing.rb +217 -0
- data/roda-3.106.0/lib/roda/plugins/typecast_params.rb +1185 -0
- data/roda-3.106.0/lib/roda/plugins/typecast_params_sized_integers.rb +108 -0
- data/roda-3.106.0/lib/roda/plugins/unescape_path.rb +41 -0
- data/roda-3.106.0/lib/roda/plugins/view_options.rb +203 -0
- data/roda-3.106.0/lib/roda/plugins/view_subdir_leading_slash.rb +49 -0
- data/roda-3.106.0/lib/roda/plugins.rb +68 -0
- data/roda-3.106.0/lib/roda/request.rb +722 -0
- data/roda-3.106.0/lib/roda/response.rb +221 -0
- data/roda-3.106.0/lib/roda/session_middleware.rb +184 -0
- data/roda-3.106.0/lib/roda/version.rb +18 -0
- data/roda-3.106.0/lib/roda.rb +741 -0
- data/ultra-max-sys.gemspec +12 -0
- 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
|