diy_rails 0.1.0
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.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +21 -0
- data/README.md +29 -0
- data/Rakefile +4 -0
- data/lib/diy_rails/version.rb +5 -0
- data/lib/diy_rails.rb +8 -0
- data/sig/diy_rails.rbs +4 -0
- data/vendor/bundle/ruby/3.0.0/bin/rackup +29 -0
- data/vendor/bundle/ruby/3.0.0/bin/rake +29 -0
- data/vendor/bundle/ruby/3.0.0/cache/rack-2.2.4.gem +0 -0
- data/vendor/bundle/ruby/3.0.0/cache/rake-13.0.6.gem +0 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/CHANGELOG.md +708 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/CONTRIBUTING.md +136 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/MIT-LICENSE +20 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/README.rdoc +306 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/Rakefile +130 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/SPEC.rdoc +288 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/bin/rackup +5 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack.png +0 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack.svg +150 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack_logo.svg +164 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rdoc.css +412 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/lobster.ru +6 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/protectedlobster.rb +16 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/protectedlobster.ru +10 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/abstract/handler.rb +39 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/abstract/request.rb +47 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/basic.rb +61 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/md5.rb +131 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/nonce.rb +54 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/params.rb +54 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/request.rb +43 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/body_proxy.rb +45 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/builder.rb +257 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/cascade.rb +68 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/chunked.rb +117 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/common_logger.rb +83 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/conditional_get.rb +83 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/config.rb +22 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/content_length.rb +38 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/content_type.rb +30 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/core_ext/regexp.rb +14 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/deflater.rb +144 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/directory.rb +199 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/etag.rb +77 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/events.rb +153 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/file.rb +7 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/files.rb +218 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/cgi.rb +59 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/fastcgi.rb +100 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/lsws.rb +61 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/scgi.rb +71 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/thin.rb +36 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/webrick.rb +129 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler.rb +104 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/head.rb +25 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lint.rb +806 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lobster.rb +70 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lock.rb +32 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/logger.rb +20 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/media_type.rb +43 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/method_override.rb +52 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/mime.rb +685 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/mock.rb +273 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/generator.rb +97 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/parser.rb +365 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/uploaded_file.rb +41 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart.rb +64 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/null_logger.rb +39 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/query_parser.rb +221 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/recursive.rb +64 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/reloader.rb +114 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/request.rb +659 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/response.rb +318 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/rewindable_input.rb +94 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/runtime.rb +34 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/sendfile.rb +162 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/server.rb +466 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/abstract/id.rb +523 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/cookie.rb +203 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/memcache.rb +10 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/pool.rb +85 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/show_exceptions.rb +390 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/show_status.rb +113 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/static.rb +187 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/tempfile_reaper.rb +22 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/urlmap.rb +97 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/utils.rb +616 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/version.rb +29 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack.rb +141 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/rack.gemspec +46 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/History.rdoc +2403 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/MIT-LICENSE +21 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/README.rdoc +155 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/command_line_usage.rdoc +158 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/Rakefile1 +38 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/Rakefile2 +35 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/a.c +6 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/b.c +6 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/main.c +11 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/glossary.rdoc +42 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/jamis.rb +592 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/proto_rake.rdoc +127 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rake.1 +156 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rakefile.rdoc +622 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rational.rdoc +151 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/exe/rake +27 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb +831 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/backtrace.rb +24 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/clean.rb +78 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/cloneable.rb +17 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/cpu_counter.rb +107 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/default_loader.rb +15 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/dsl_definition.rb +195 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/early_time.rb +22 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/ext/core.rb +26 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/ext/string.rb +176 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_creation_task.rb +25 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_list.rb +435 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_task.rb +54 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_utils.rb +134 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_utils_ext.rb +134 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/invocation_chain.rb +57 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/invocation_exception_mixin.rb +17 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/late_time.rb +18 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/linked_list.rb +112 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/loaders/makefile.rb +54 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/multi_task.rb +14 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/name_space.rb +38 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/packagetask.rb +222 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/phony.rb +16 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/private_reader.rb +21 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/promise.rb +100 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/pseudo_status.rb +30 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rake_module.rb +67 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rake_test_loader.rb +27 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rule_recursion_overflow_error.rb +20 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/scope.rb +43 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb +434 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_argument_error.rb +8 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_arguments.rb +109 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_manager.rb +331 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/tasklib.rb +12 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/testtask.rb +189 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/thread_history_display.rb +49 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/thread_pool.rb +163 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/trace_output.rb +23 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/version.rb +10 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/win32.rb +51 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake.rb +71 -0
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/rake.gemspec +100 -0
- data/vendor/bundle/ruby/3.0.0/specifications/rack-2.2.4.gemspec +41 -0
- data/vendor/bundle/ruby/3.0.0/specifications/rake-13.0.6.gemspec +26 -0
- metadata +210 -0
@@ -0,0 +1,221 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class QueryParser
|
5
|
+
(require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
|
6
|
+
|
7
|
+
DEFAULT_SEP = /[&;] */n
|
8
|
+
COMMON_SEP = { ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n }
|
9
|
+
|
10
|
+
# ParameterTypeError is the error that is raised when incoming structural
|
11
|
+
# parameters (parsed by parse_nested_query) contain conflicting types.
|
12
|
+
class ParameterTypeError < TypeError; end
|
13
|
+
|
14
|
+
# InvalidParameterError is the error that is raised when incoming structural
|
15
|
+
# parameters (parsed by parse_nested_query) contain invalid format or byte
|
16
|
+
# sequence.
|
17
|
+
class InvalidParameterError < ArgumentError; end
|
18
|
+
|
19
|
+
# ParamsTooDeepError is the error that is raised when params are recursively
|
20
|
+
# nested over the specified limit.
|
21
|
+
class ParamsTooDeepError < RangeError; end
|
22
|
+
|
23
|
+
def self.make_default(key_space_limit, param_depth_limit)
|
24
|
+
new Params, key_space_limit, param_depth_limit
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :key_space_limit, :param_depth_limit
|
28
|
+
|
29
|
+
def initialize(params_class, key_space_limit, param_depth_limit)
|
30
|
+
@params_class = params_class
|
31
|
+
@key_space_limit = key_space_limit
|
32
|
+
@param_depth_limit = param_depth_limit
|
33
|
+
end
|
34
|
+
|
35
|
+
# Stolen from Mongrel, with some small modifications:
|
36
|
+
# Parses a query string by breaking it up at the '&'
|
37
|
+
# and ';' characters. You can also use this to parse
|
38
|
+
# cookies by changing the characters used in the second
|
39
|
+
# parameter (which defaults to '&;').
|
40
|
+
def parse_query(qs, d = nil, &unescaper)
|
41
|
+
unescaper ||= method(:unescape)
|
42
|
+
|
43
|
+
params = make_params
|
44
|
+
|
45
|
+
(qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
|
46
|
+
next if p.empty?
|
47
|
+
k, v = p.split('=', 2).map!(&unescaper)
|
48
|
+
|
49
|
+
if cur = params[k]
|
50
|
+
if cur.class == Array
|
51
|
+
params[k] << v
|
52
|
+
else
|
53
|
+
params[k] = [cur, v]
|
54
|
+
end
|
55
|
+
else
|
56
|
+
params[k] = v
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
return params.to_h
|
61
|
+
end
|
62
|
+
|
63
|
+
# parse_nested_query expands a query string into structural types. Supported
|
64
|
+
# types are Arrays, Hashes and basic value types. It is possible to supply
|
65
|
+
# query strings with parameters of conflicting types, in this case a
|
66
|
+
# ParameterTypeError is raised. Users are encouraged to return a 400 in this
|
67
|
+
# case.
|
68
|
+
def parse_nested_query(qs, d = nil)
|
69
|
+
params = make_params
|
70
|
+
|
71
|
+
unless qs.nil? || qs.empty?
|
72
|
+
(qs || '').split(d ? (COMMON_SEP[d] || /[#{d}] */n) : DEFAULT_SEP).each do |p|
|
73
|
+
k, v = p.split('=', 2).map! { |s| unescape(s) }
|
74
|
+
|
75
|
+
normalize_params(params, k, v, param_depth_limit)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
return params.to_h
|
80
|
+
rescue ArgumentError => e
|
81
|
+
raise InvalidParameterError, e.message, e.backtrace
|
82
|
+
end
|
83
|
+
|
84
|
+
# normalize_params recursively expands parameters into structural types. If
|
85
|
+
# the structural types represented by two different parameter names are in
|
86
|
+
# conflict, a ParameterTypeError is raised.
|
87
|
+
def normalize_params(params, name, v, depth)
|
88
|
+
raise ParamsTooDeepError if depth <= 0
|
89
|
+
|
90
|
+
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
91
|
+
k = $1 || ''
|
92
|
+
after = $' || ''
|
93
|
+
|
94
|
+
if k.empty?
|
95
|
+
if !v.nil? && name == "[]"
|
96
|
+
return Array(v)
|
97
|
+
else
|
98
|
+
return
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
if after == ''
|
103
|
+
params[k] = v
|
104
|
+
elsif after == "["
|
105
|
+
params[name] = v
|
106
|
+
elsif after == "[]"
|
107
|
+
params[k] ||= []
|
108
|
+
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
109
|
+
params[k] << v
|
110
|
+
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
|
111
|
+
child_key = $1
|
112
|
+
params[k] ||= []
|
113
|
+
raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
|
114
|
+
if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
|
115
|
+
normalize_params(params[k].last, child_key, v, depth - 1)
|
116
|
+
else
|
117
|
+
params[k] << normalize_params(make_params, child_key, v, depth - 1)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
params[k] ||= make_params
|
121
|
+
raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
|
122
|
+
params[k] = normalize_params(params[k], after, v, depth - 1)
|
123
|
+
end
|
124
|
+
|
125
|
+
params
|
126
|
+
end
|
127
|
+
|
128
|
+
def make_params
|
129
|
+
@params_class.new @key_space_limit
|
130
|
+
end
|
131
|
+
|
132
|
+
def new_space_limit(key_space_limit)
|
133
|
+
self.class.new @params_class, key_space_limit, param_depth_limit
|
134
|
+
end
|
135
|
+
|
136
|
+
def new_depth_limit(param_depth_limit)
|
137
|
+
self.class.new @params_class, key_space_limit, param_depth_limit
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def params_hash_type?(obj)
|
143
|
+
obj.kind_of?(@params_class)
|
144
|
+
end
|
145
|
+
|
146
|
+
def params_hash_has_key?(hash, key)
|
147
|
+
return false if /\[\]/.match?(key)
|
148
|
+
|
149
|
+
key.split(/[\[\]]+/).inject(hash) do |h, part|
|
150
|
+
next h if part == ''
|
151
|
+
return false unless params_hash_type?(h) && h.key?(part)
|
152
|
+
h[part]
|
153
|
+
end
|
154
|
+
|
155
|
+
true
|
156
|
+
end
|
157
|
+
|
158
|
+
def unescape(s)
|
159
|
+
Utils.unescape(s)
|
160
|
+
end
|
161
|
+
|
162
|
+
class Params
|
163
|
+
def initialize(limit)
|
164
|
+
@limit = limit
|
165
|
+
@size = 0
|
166
|
+
@params = {}
|
167
|
+
end
|
168
|
+
|
169
|
+
def [](key)
|
170
|
+
@params[key]
|
171
|
+
end
|
172
|
+
|
173
|
+
def []=(key, value)
|
174
|
+
@size += key.size if key && !@params.key?(key)
|
175
|
+
raise ParamsTooDeepError, 'exceeded available parameter key space' if @size > @limit
|
176
|
+
@params[key] = value
|
177
|
+
end
|
178
|
+
|
179
|
+
def key?(key)
|
180
|
+
@params.key?(key)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Recursively unwraps nested `Params` objects and constructs an object
|
184
|
+
# of the same shape, but using the objects' internal representations
|
185
|
+
# (Ruby hashes) in place of the objects. The result is a hash consisting
|
186
|
+
# purely of Ruby primitives.
|
187
|
+
#
|
188
|
+
# Mutation warning!
|
189
|
+
#
|
190
|
+
# 1. This method mutates the internal representation of the `Params`
|
191
|
+
# objects in order to save object allocations.
|
192
|
+
#
|
193
|
+
# 2. The value you get back is a reference to the internal hash
|
194
|
+
# representation, not a copy.
|
195
|
+
#
|
196
|
+
# 3. Because the `Params` object's internal representation is mutable
|
197
|
+
# through the `#[]=` method, it is not thread safe. The result of
|
198
|
+
# getting the hash representation while another thread is adding a
|
199
|
+
# key to it is non-deterministic.
|
200
|
+
#
|
201
|
+
def to_h
|
202
|
+
@params.each do |key, value|
|
203
|
+
case value
|
204
|
+
when self
|
205
|
+
# Handle circular references gracefully.
|
206
|
+
@params[key] = @params
|
207
|
+
when Params
|
208
|
+
@params[key] = value.to_h
|
209
|
+
when Array
|
210
|
+
value.map! { |v| v.kind_of?(Params) ? v.to_h : v }
|
211
|
+
else
|
212
|
+
# Ignore anything that is not a `Params` object or
|
213
|
+
# a collection that can contain one.
|
214
|
+
end
|
215
|
+
end
|
216
|
+
@params
|
217
|
+
end
|
218
|
+
alias_method :to_params_hash, :to_h
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
# Rack::ForwardRequest gets caught by Rack::Recursive and redirects
|
7
|
+
# the current request to the app at +url+.
|
8
|
+
#
|
9
|
+
# raise ForwardRequest.new("/not-found")
|
10
|
+
#
|
11
|
+
|
12
|
+
class ForwardRequest < Exception
|
13
|
+
attr_reader :url, :env
|
14
|
+
|
15
|
+
def initialize(url, env = {})
|
16
|
+
@url = URI(url)
|
17
|
+
@env = env
|
18
|
+
|
19
|
+
@env[PATH_INFO] = @url.path
|
20
|
+
@env[QUERY_STRING] = @url.query if @url.query
|
21
|
+
@env[HTTP_HOST] = @url.host if @url.host
|
22
|
+
@env[HTTP_PORT] = @url.port if @url.port
|
23
|
+
@env[RACK_URL_SCHEME] = @url.scheme if @url.scheme
|
24
|
+
|
25
|
+
super "forwarding to #{url}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Rack::Recursive allows applications called down the chain to
|
30
|
+
# include data from other applications (by using
|
31
|
+
# <tt>rack['rack.recursive.include'][...]</tt> or raise a
|
32
|
+
# ForwardRequest to redirect internally.
|
33
|
+
|
34
|
+
class Recursive
|
35
|
+
def initialize(app)
|
36
|
+
@app = app
|
37
|
+
end
|
38
|
+
|
39
|
+
def call(env)
|
40
|
+
dup._call(env)
|
41
|
+
end
|
42
|
+
|
43
|
+
def _call(env)
|
44
|
+
@script_name = env[SCRIPT_NAME]
|
45
|
+
@app.call(env.merge(RACK_RECURSIVE_INCLUDE => method(:include)))
|
46
|
+
rescue ForwardRequest => req
|
47
|
+
call(env.merge(req.env))
|
48
|
+
end
|
49
|
+
|
50
|
+
def include(env, path)
|
51
|
+
unless path.index(@script_name) == 0 && (path[@script_name.size] == ?/ ||
|
52
|
+
path[@script_name.size].nil?)
|
53
|
+
raise ArgumentError, "can only include below #{@script_name}, not #{path}"
|
54
|
+
end
|
55
|
+
|
56
|
+
env = env.merge(PATH_INFO => path,
|
57
|
+
SCRIPT_NAME => @script_name,
|
58
|
+
REQUEST_METHOD => GET,
|
59
|
+
"CONTENT_LENGTH" => "0", "CONTENT_TYPE" => "",
|
60
|
+
RACK_INPUT => StringIO.new(""))
|
61
|
+
@app.call(env)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2009-2018 Michael Fellinger <m.fellinger@gmail.com>
|
4
|
+
# Rack::Reloader is subject to the terms of an MIT-style license.
|
5
|
+
# See MIT-LICENSE or https://opensource.org/licenses/MIT.
|
6
|
+
|
7
|
+
require 'pathname'
|
8
|
+
|
9
|
+
module Rack
|
10
|
+
|
11
|
+
# High performant source reloader
|
12
|
+
#
|
13
|
+
# This class acts as Rack middleware.
|
14
|
+
#
|
15
|
+
# What makes it especially suited for use in a production environment is that
|
16
|
+
# any file will only be checked once and there will only be made one system
|
17
|
+
# call stat(2).
|
18
|
+
#
|
19
|
+
# Please note that this will not reload files in the background, it does so
|
20
|
+
# only when actively called.
|
21
|
+
#
|
22
|
+
# It is performing a check/reload cycle at the start of every request, but
|
23
|
+
# also respects a cool down time, during which nothing will be done.
|
24
|
+
class Reloader
|
25
|
+
(require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
|
26
|
+
|
27
|
+
def initialize(app, cooldown = 10, backend = Stat)
|
28
|
+
@app = app
|
29
|
+
@cooldown = cooldown
|
30
|
+
@last = (Time.now - cooldown)
|
31
|
+
@cache = {}
|
32
|
+
@mtimes = {}
|
33
|
+
@reload_mutex = Mutex.new
|
34
|
+
|
35
|
+
extend backend
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(env)
|
39
|
+
if @cooldown and Time.now > @last + @cooldown
|
40
|
+
if Thread.list.size > 1
|
41
|
+
@reload_mutex.synchronize{ reload! }
|
42
|
+
else
|
43
|
+
reload!
|
44
|
+
end
|
45
|
+
|
46
|
+
@last = Time.now
|
47
|
+
end
|
48
|
+
|
49
|
+
@app.call(env)
|
50
|
+
end
|
51
|
+
|
52
|
+
def reload!(stderr = $stderr)
|
53
|
+
rotation do |file, mtime|
|
54
|
+
previous_mtime = @mtimes[file] ||= mtime
|
55
|
+
safe_load(file, mtime, stderr) if mtime > previous_mtime
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# A safe Kernel::load, issuing the hooks depending on the results
|
60
|
+
def safe_load(file, mtime, stderr = $stderr)
|
61
|
+
load(file)
|
62
|
+
stderr.puts "#{self.class}: reloaded `#{file}'"
|
63
|
+
file
|
64
|
+
rescue LoadError, SyntaxError => ex
|
65
|
+
stderr.puts ex
|
66
|
+
ensure
|
67
|
+
@mtimes[file] = mtime
|
68
|
+
end
|
69
|
+
|
70
|
+
module Stat
|
71
|
+
def rotation
|
72
|
+
files = [$0, *$LOADED_FEATURES].uniq
|
73
|
+
paths = ['./', *$LOAD_PATH].uniq
|
74
|
+
|
75
|
+
files.map{|file|
|
76
|
+
next if /\.(so|bundle)$/.match?(file) # cannot reload compiled files
|
77
|
+
|
78
|
+
found, stat = figure_path(file, paths)
|
79
|
+
next unless found && stat && mtime = stat.mtime
|
80
|
+
|
81
|
+
@cache[file] = found
|
82
|
+
|
83
|
+
yield(found, mtime)
|
84
|
+
}.compact
|
85
|
+
end
|
86
|
+
|
87
|
+
# Takes a relative or absolute +file+ name, a couple possible +paths+ that
|
88
|
+
# the +file+ might reside in. Returns the full path and File::Stat for the
|
89
|
+
# path.
|
90
|
+
def figure_path(file, paths)
|
91
|
+
found = @cache[file]
|
92
|
+
found = file if !found and Pathname.new(file).absolute?
|
93
|
+
found, stat = safe_stat(found)
|
94
|
+
return found, stat if found
|
95
|
+
|
96
|
+
paths.find do |possible_path|
|
97
|
+
path = ::File.join(possible_path, file)
|
98
|
+
found, stat = safe_stat(path)
|
99
|
+
return ::File.expand_path(found), stat if found
|
100
|
+
end
|
101
|
+
|
102
|
+
return false, false
|
103
|
+
end
|
104
|
+
|
105
|
+
def safe_stat(file)
|
106
|
+
return unless file
|
107
|
+
stat = ::File.stat(file)
|
108
|
+
return file, stat if stat.file?
|
109
|
+
rescue Errno::ENOENT, Errno::ENOTDIR, Errno::ESRCH
|
110
|
+
@cache.delete(file) and false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|