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.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -0
  3. data/Gemfile.lock +21 -0
  4. data/README.md +29 -0
  5. data/Rakefile +4 -0
  6. data/lib/diy_rails/version.rb +5 -0
  7. data/lib/diy_rails.rb +8 -0
  8. data/sig/diy_rails.rbs +4 -0
  9. data/vendor/bundle/ruby/3.0.0/bin/rackup +29 -0
  10. data/vendor/bundle/ruby/3.0.0/bin/rake +29 -0
  11. data/vendor/bundle/ruby/3.0.0/cache/rack-2.2.4.gem +0 -0
  12. data/vendor/bundle/ruby/3.0.0/cache/rake-13.0.6.gem +0 -0
  13. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/CHANGELOG.md +708 -0
  14. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/CONTRIBUTING.md +136 -0
  15. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/MIT-LICENSE +20 -0
  16. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/README.rdoc +306 -0
  17. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/Rakefile +130 -0
  18. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/SPEC.rdoc +288 -0
  19. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/bin/rackup +5 -0
  20. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack.png +0 -0
  21. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack.svg +150 -0
  22. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack_logo.svg +164 -0
  23. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rdoc.css +412 -0
  24. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/lobster.ru +6 -0
  25. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/protectedlobster.rb +16 -0
  26. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/protectedlobster.ru +10 -0
  27. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/abstract/handler.rb +39 -0
  28. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/abstract/request.rb +47 -0
  29. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/basic.rb +61 -0
  30. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/md5.rb +131 -0
  31. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/nonce.rb +54 -0
  32. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/params.rb +54 -0
  33. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/request.rb +43 -0
  34. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/body_proxy.rb +45 -0
  35. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/builder.rb +257 -0
  36. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/cascade.rb +68 -0
  37. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/chunked.rb +117 -0
  38. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/common_logger.rb +83 -0
  39. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/conditional_get.rb +83 -0
  40. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/config.rb +22 -0
  41. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/content_length.rb +38 -0
  42. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/content_type.rb +30 -0
  43. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/core_ext/regexp.rb +14 -0
  44. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/deflater.rb +144 -0
  45. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/directory.rb +199 -0
  46. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/etag.rb +77 -0
  47. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/events.rb +153 -0
  48. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/file.rb +7 -0
  49. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/files.rb +218 -0
  50. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/cgi.rb +59 -0
  51. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/fastcgi.rb +100 -0
  52. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/lsws.rb +61 -0
  53. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/scgi.rb +71 -0
  54. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/thin.rb +36 -0
  55. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/webrick.rb +129 -0
  56. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler.rb +104 -0
  57. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/head.rb +25 -0
  58. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lint.rb +806 -0
  59. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lobster.rb +70 -0
  60. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lock.rb +32 -0
  61. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/logger.rb +20 -0
  62. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/media_type.rb +43 -0
  63. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/method_override.rb +52 -0
  64. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/mime.rb +685 -0
  65. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/mock.rb +273 -0
  66. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/generator.rb +97 -0
  67. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/parser.rb +365 -0
  68. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/uploaded_file.rb +41 -0
  69. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart.rb +64 -0
  70. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/null_logger.rb +39 -0
  71. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/query_parser.rb +221 -0
  72. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/recursive.rb +64 -0
  73. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/reloader.rb +114 -0
  74. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/request.rb +659 -0
  75. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/response.rb +318 -0
  76. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/rewindable_input.rb +94 -0
  77. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/runtime.rb +34 -0
  78. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/sendfile.rb +162 -0
  79. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/server.rb +466 -0
  80. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/abstract/id.rb +523 -0
  81. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/cookie.rb +203 -0
  82. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/memcache.rb +10 -0
  83. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/pool.rb +85 -0
  84. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/show_exceptions.rb +390 -0
  85. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/show_status.rb +113 -0
  86. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/static.rb +187 -0
  87. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/tempfile_reaper.rb +22 -0
  88. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/urlmap.rb +97 -0
  89. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/utils.rb +616 -0
  90. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/version.rb +29 -0
  91. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack.rb +141 -0
  92. data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/rack.gemspec +46 -0
  93. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/History.rdoc +2403 -0
  94. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/MIT-LICENSE +21 -0
  95. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/README.rdoc +155 -0
  96. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/command_line_usage.rdoc +158 -0
  97. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/Rakefile1 +38 -0
  98. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/Rakefile2 +35 -0
  99. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/a.c +6 -0
  100. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/b.c +6 -0
  101. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/main.c +11 -0
  102. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/glossary.rdoc +42 -0
  103. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/jamis.rb +592 -0
  104. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/proto_rake.rdoc +127 -0
  105. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rake.1 +156 -0
  106. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rakefile.rdoc +622 -0
  107. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rational.rdoc +151 -0
  108. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/exe/rake +27 -0
  109. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb +831 -0
  110. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/backtrace.rb +24 -0
  111. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/clean.rb +78 -0
  112. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/cloneable.rb +17 -0
  113. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/cpu_counter.rb +107 -0
  114. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/default_loader.rb +15 -0
  115. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/dsl_definition.rb +195 -0
  116. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/early_time.rb +22 -0
  117. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/ext/core.rb +26 -0
  118. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/ext/string.rb +176 -0
  119. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_creation_task.rb +25 -0
  120. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_list.rb +435 -0
  121. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_task.rb +54 -0
  122. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_utils.rb +134 -0
  123. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_utils_ext.rb +134 -0
  124. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/invocation_chain.rb +57 -0
  125. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/invocation_exception_mixin.rb +17 -0
  126. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/late_time.rb +18 -0
  127. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/linked_list.rb +112 -0
  128. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/loaders/makefile.rb +54 -0
  129. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/multi_task.rb +14 -0
  130. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/name_space.rb +38 -0
  131. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/packagetask.rb +222 -0
  132. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/phony.rb +16 -0
  133. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/private_reader.rb +21 -0
  134. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/promise.rb +100 -0
  135. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/pseudo_status.rb +30 -0
  136. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rake_module.rb +67 -0
  137. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rake_test_loader.rb +27 -0
  138. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rule_recursion_overflow_error.rb +20 -0
  139. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/scope.rb +43 -0
  140. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb +434 -0
  141. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_argument_error.rb +8 -0
  142. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_arguments.rb +109 -0
  143. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_manager.rb +331 -0
  144. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/tasklib.rb +12 -0
  145. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/testtask.rb +189 -0
  146. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/thread_history_display.rb +49 -0
  147. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/thread_pool.rb +163 -0
  148. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/trace_output.rb +23 -0
  149. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/version.rb +10 -0
  150. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/win32.rb +51 -0
  151. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake.rb +71 -0
  152. data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/rake.gemspec +100 -0
  153. data/vendor/bundle/ruby/3.0.0/specifications/rack-2.2.4.gemspec +41 -0
  154. data/vendor/bundle/ruby/3.0.0/specifications/rake-13.0.6.gemspec +26 -0
  155. 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