nano-sharp-hub 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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/nano-sharp-hub.gemspec +12 -0
  3. data/rack-3.2.6/CHANGELOG.md +1346 -0
  4. data/rack-3.2.6/CONTRIBUTING.md +144 -0
  5. data/rack-3.2.6/MIT-LICENSE +20 -0
  6. data/rack-3.2.6/README.md +384 -0
  7. data/rack-3.2.6/SPEC.rdoc +258 -0
  8. data/rack-3.2.6/lib/rack/auth/abstract/handler.rb +41 -0
  9. data/rack-3.2.6/lib/rack/auth/abstract/request.rb +51 -0
  10. data/rack-3.2.6/lib/rack/auth/basic.rb +58 -0
  11. data/rack-3.2.6/lib/rack/bad_request.rb +8 -0
  12. data/rack-3.2.6/lib/rack/body_proxy.rb +63 -0
  13. data/rack-3.2.6/lib/rack/builder.rb +296 -0
  14. data/rack-3.2.6/lib/rack/cascade.rb +67 -0
  15. data/rack-3.2.6/lib/rack/common_logger.rb +89 -0
  16. data/rack-3.2.6/lib/rack/conditional_get.rb +87 -0
  17. data/rack-3.2.6/lib/rack/config.rb +22 -0
  18. data/rack-3.2.6/lib/rack/constants.rb +68 -0
  19. data/rack-3.2.6/lib/rack/content_length.rb +34 -0
  20. data/rack-3.2.6/lib/rack/content_type.rb +33 -0
  21. data/rack-3.2.6/lib/rack/deflater.rb +158 -0
  22. data/rack-3.2.6/lib/rack/directory.rb +208 -0
  23. data/rack-3.2.6/lib/rack/etag.rb +71 -0
  24. data/rack-3.2.6/lib/rack/events.rb +172 -0
  25. data/rack-3.2.6/lib/rack/files.rb +216 -0
  26. data/rack-3.2.6/lib/rack/head.rb +25 -0
  27. data/rack-3.2.6/lib/rack/headers.rb +238 -0
  28. data/rack-3.2.6/lib/rack/lint.rb +964 -0
  29. data/rack-3.2.6/lib/rack/lock.rb +29 -0
  30. data/rack-3.2.6/lib/rack/media_type.rb +52 -0
  31. data/rack-3.2.6/lib/rack/method_override.rb +56 -0
  32. data/rack-3.2.6/lib/rack/mime.rb +694 -0
  33. data/rack-3.2.6/lib/rack/mock.rb +3 -0
  34. data/rack-3.2.6/lib/rack/mock_request.rb +161 -0
  35. data/rack-3.2.6/lib/rack/mock_response.rb +156 -0
  36. data/rack-3.2.6/lib/rack/multipart/generator.rb +99 -0
  37. data/rack-3.2.6/lib/rack/multipart/parser.rb +621 -0
  38. data/rack-3.2.6/lib/rack/multipart/uploaded_file.rb +82 -0
  39. data/rack-3.2.6/lib/rack/multipart.rb +77 -0
  40. data/rack-3.2.6/lib/rack/null_logger.rb +48 -0
  41. data/rack-3.2.6/lib/rack/query_parser.rb +261 -0
  42. data/rack-3.2.6/lib/rack/recursive.rb +66 -0
  43. data/rack-3.2.6/lib/rack/reloader.rb +112 -0
  44. data/rack-3.2.6/lib/rack/request.rb +790 -0
  45. data/rack-3.2.6/lib/rack/response.rb +403 -0
  46. data/rack-3.2.6/lib/rack/rewindable_input.rb +116 -0
  47. data/rack-3.2.6/lib/rack/runtime.rb +35 -0
  48. data/rack-3.2.6/lib/rack/sendfile.rb +197 -0
  49. data/rack-3.2.6/lib/rack/show_exceptions.rb +409 -0
  50. data/rack-3.2.6/lib/rack/show_status.rb +121 -0
  51. data/rack-3.2.6/lib/rack/static.rb +192 -0
  52. data/rack-3.2.6/lib/rack/tempfile_reaper.rb +33 -0
  53. data/rack-3.2.6/lib/rack/urlmap.rb +99 -0
  54. data/rack-3.2.6/lib/rack/utils.rb +714 -0
  55. data/rack-3.2.6/lib/rack/version.rb +17 -0
  56. data/rack-3.2.6/lib/rack.rb +64 -0
  57. metadata +96 -0
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'constants'
4
+ require_relative 'utils'
5
+
6
+ require_relative 'multipart/parser'
7
+ require_relative 'multipart/generator'
8
+
9
+ require_relative 'bad_request'
10
+
11
+ module Rack
12
+ # A multipart form data parser, adapted from IOWA.
13
+ #
14
+ # Usually, Rack::Request#POST takes care of calling this.
15
+ module Multipart
16
+ MULTIPART_BOUNDARY = "AaB03x"
17
+
18
+ class MissingInputError < StandardError
19
+ include BadRequest
20
+ end
21
+
22
+ # Accumulator for multipart form data, conforming to the QueryParser API.
23
+ # In future, the Parser could return the pair list directly, but that would
24
+ # change its API.
25
+ class ParamList # :nodoc:
26
+ def self.make_params
27
+ new
28
+ end
29
+
30
+ def self.normalize_params(params, key, value)
31
+ params << [key, value]
32
+ end
33
+
34
+ def initialize
35
+ @pairs = []
36
+ end
37
+
38
+ def <<(pair)
39
+ @pairs << pair
40
+ end
41
+
42
+ def to_params_hash
43
+ @pairs
44
+ end
45
+ end
46
+
47
+ class << self
48
+ def parse_multipart(env, params = Rack::Utils.default_query_parser)
49
+ unless io = env[RACK_INPUT]
50
+ raise MissingInputError, "Missing input stream!"
51
+ end
52
+
53
+ if content_length = env['CONTENT_LENGTH']
54
+ content_length = content_length.to_i
55
+ end
56
+
57
+ content_type = env['CONTENT_TYPE']
58
+
59
+ tempfile = env[RACK_MULTIPART_TEMPFILE_FACTORY] || Parser::TEMPFILE_FACTORY
60
+ bufsize = env[RACK_MULTIPART_BUFFER_SIZE] || Parser::BUFSIZE
61
+
62
+ info = Parser.parse(io, content_length, content_type, tempfile, bufsize, params)
63
+ env[RACK_TEMPFILES] = info.tmp_files
64
+
65
+ return info.params
66
+ end
67
+
68
+ def extract_multipart(request, params = Rack::Utils.default_query_parser)
69
+ parse_multipart(request.env)
70
+ end
71
+
72
+ def build_multipart(params, first = true)
73
+ Generator.new(params, first).dump
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'constants'
4
+
5
+ module Rack
6
+ class NullLogger
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[RACK_LOGGER] = self
13
+ @app.call(env)
14
+ end
15
+
16
+ def info(progname = nil, &block); end
17
+ def debug(progname = nil, &block); end
18
+ def warn(progname = nil, &block); end
19
+ def error(progname = nil, &block); end
20
+ def fatal(progname = nil, &block); end
21
+ def unknown(progname = nil, &block); end
22
+ def info? ; end
23
+ def debug? ; end
24
+ def warn? ; end
25
+ def error? ; end
26
+ def fatal? ; end
27
+ def debug! ; end
28
+ def error! ; end
29
+ def fatal! ; end
30
+ def info! ; end
31
+ def warn! ; end
32
+ def level ; end
33
+ def progname ; end
34
+ def datetime_format ; end
35
+ def formatter ; end
36
+ def sev_threshold ; end
37
+ def level=(level); end
38
+ def progname=(progname); end
39
+ def datetime_format=(datetime_format); end
40
+ def formatter=(formatter); end
41
+ def sev_threshold=(sev_threshold); end
42
+ def close ; end
43
+ def add(severity, message = nil, progname = nil, &block); end
44
+ def log(severity, message = nil, progname = nil, &block); end
45
+ def <<(msg); end
46
+ def reopen(logdev = nil); end
47
+ end
48
+ end
@@ -0,0 +1,261 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'bad_request'
4
+ require 'uri'
5
+
6
+ module Rack
7
+ class QueryParser
8
+ DEFAULT_SEP = /& */n
9
+ COMMON_SEP = { ";" => /; */n, ";," => /[;,] */n, "&" => /& */n }
10
+
11
+ # ParameterTypeError is the error that is raised when incoming structural
12
+ # parameters (parsed by parse_nested_query) contain conflicting types.
13
+ class ParameterTypeError < TypeError
14
+ include BadRequest
15
+ end
16
+
17
+ # InvalidParameterError is the error that is raised when incoming structural
18
+ # parameters (parsed by parse_nested_query) contain invalid format or byte
19
+ # sequence.
20
+ class InvalidParameterError < ArgumentError
21
+ include BadRequest
22
+ end
23
+
24
+ # QueryLimitError is for errors raised when the query provided exceeds one
25
+ # of the query parser limits.
26
+ class QueryLimitError < RangeError
27
+ include BadRequest
28
+ end
29
+
30
+ # ParamsTooDeepError is the old name for the error that is raised when params
31
+ # are recursively nested over the specified limit. Make it the same as
32
+ # as QueryLimitError, so that code that rescues ParamsTooDeepError error
33
+ # to handle bad query strings also now handles other limits.
34
+ ParamsTooDeepError = QueryLimitError
35
+
36
+ def self.make_default(param_depth_limit, **options)
37
+ new(Params, param_depth_limit, **options)
38
+ end
39
+
40
+ attr_reader :param_depth_limit
41
+
42
+ env_int = lambda do |key, val|
43
+ if str_val = ENV[key]
44
+ begin
45
+ val = Integer(str_val, 10)
46
+ rescue ArgumentError
47
+ raise ArgumentError, "non-integer value provided for environment variable #{key}"
48
+ end
49
+ end
50
+
51
+ val
52
+ end
53
+
54
+ BYTESIZE_LIMIT = env_int.call("RACK_QUERY_PARSER_BYTESIZE_LIMIT", 4194304)
55
+ private_constant :BYTESIZE_LIMIT
56
+
57
+ PARAMS_LIMIT = env_int.call("RACK_QUERY_PARSER_PARAMS_LIMIT", 4096)
58
+ private_constant :PARAMS_LIMIT
59
+
60
+ attr_reader :bytesize_limit
61
+
62
+ def initialize(params_class, param_depth_limit, bytesize_limit: BYTESIZE_LIMIT, params_limit: PARAMS_LIMIT)
63
+ @params_class = params_class
64
+ @param_depth_limit = param_depth_limit
65
+ @bytesize_limit = bytesize_limit
66
+ @params_limit = params_limit
67
+ end
68
+
69
+ # Stolen from Mongrel, with some small modifications:
70
+ # Parses a query string by breaking it up at the '&'. You can also use this
71
+ # to parse cookies by changing the characters used in the second parameter
72
+ # (which defaults to '&').
73
+ def parse_query(qs, separator = nil, &unescaper)
74
+ params = make_params
75
+
76
+ each_query_pair(qs, separator, unescaper) do |k, v|
77
+ if cur = params[k]
78
+ if cur.class == Array
79
+ params[k] << v
80
+ else
81
+ params[k] = [cur, v]
82
+ end
83
+ else
84
+ params[k] = v
85
+ end
86
+ end
87
+
88
+ return params.to_h
89
+ end
90
+
91
+ # Parses a query string by breaking it up at the '&', returning all key-value
92
+ # pairs as an array of [key, value] arrays. Unlike parse_query, this preserves
93
+ # all duplicate keys rather than collapsing them.
94
+ def parse_query_pairs(qs, separator = nil)
95
+ pairs = []
96
+
97
+ each_query_pair(qs, separator) do |k, v|
98
+ pairs << [k, v]
99
+ end
100
+
101
+ pairs
102
+ end
103
+
104
+ # parse_nested_query expands a query string into structural types. Supported
105
+ # types are Arrays, Hashes and basic value types. It is possible to supply
106
+ # query strings with parameters of conflicting types, in this case a
107
+ # ParameterTypeError is raised. Users are encouraged to return a 400 in this
108
+ # case.
109
+ def parse_nested_query(qs, separator = nil)
110
+ params = make_params
111
+
112
+ each_query_pair(qs, separator) do |k, v|
113
+ _normalize_params(params, k, v, 0)
114
+ end
115
+
116
+ return params.to_h
117
+ end
118
+
119
+ # normalize_params recursively expands parameters into structural types. If
120
+ # the structural types represented by two different parameter names are in
121
+ # conflict, a ParameterTypeError is raised. The depth argument is deprecated
122
+ # and should no longer be used, it is kept for backwards compatibility with
123
+ # earlier versions of rack.
124
+ def normalize_params(params, name, v, _depth=nil)
125
+ _normalize_params(params, name, v, 0)
126
+ end
127
+
128
+ private def _normalize_params(params, name, v, depth)
129
+ raise ParamsTooDeepError if depth >= param_depth_limit
130
+
131
+ if !name
132
+ # nil name, treat same as empty string (required by tests)
133
+ k = after = ''
134
+ elsif depth == 0
135
+ # Start of parsing, don't treat [] or [ at start of string specially
136
+ if start = name.index('[', 1)
137
+ # Start of parameter nesting, use part before brackets as key
138
+ k = name[0, start]
139
+ after = name[start, name.length]
140
+ else
141
+ # Plain parameter with no nesting
142
+ k = name
143
+ after = ''
144
+ end
145
+ elsif name.start_with?('[]')
146
+ # Array nesting
147
+ k = '[]'
148
+ after = name[2, name.length]
149
+ elsif name.start_with?('[') && (start = name.index(']', 1))
150
+ # Hash nesting, use the part inside brackets as the key
151
+ k = name[1, start-1]
152
+ after = name[start+1, name.length]
153
+ else
154
+ # Probably malformed input, nested but not starting with [
155
+ # treat full name as key for backwards compatibility.
156
+ k = name
157
+ after = ''
158
+ end
159
+
160
+ return if k.empty?
161
+
162
+ if after == ''
163
+ if k == '[]' && depth != 0
164
+ return [v]
165
+ else
166
+ params[k] = v
167
+ end
168
+ elsif after == "["
169
+ params[name] = v
170
+ elsif after == "[]"
171
+ params[k] ||= []
172
+ raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
173
+ params[k] << v
174
+ elsif after.start_with?('[]')
175
+ # Recognize x[][y] (hash inside array) parameters
176
+ unless after[2] == '[' && after.end_with?(']') && (child_key = after[3, after.length-4]) && !child_key.empty? && !child_key.index('[') && !child_key.index(']')
177
+ # Handle other nested array parameters
178
+ child_key = after[2, after.length]
179
+ end
180
+ params[k] ||= []
181
+ raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
182
+ if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key)
183
+ _normalize_params(params[k].last, child_key, v, depth + 1)
184
+ else
185
+ params[k] << _normalize_params(make_params, child_key, v, depth + 1)
186
+ end
187
+ else
188
+ params[k] ||= make_params
189
+ raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k])
190
+ params[k] = _normalize_params(params[k], after, v, depth + 1)
191
+ end
192
+
193
+ params
194
+ end
195
+
196
+ def make_params
197
+ @params_class.new
198
+ end
199
+
200
+ def new_depth_limit(param_depth_limit)
201
+ self.class.new @params_class, param_depth_limit
202
+ end
203
+
204
+ private
205
+
206
+ def params_hash_type?(obj)
207
+ obj.kind_of?(@params_class)
208
+ end
209
+
210
+ def params_hash_has_key?(hash, key)
211
+ return false if /\[\]/.match?(key)
212
+
213
+ key.split(/[\[\]]+/).inject(hash) do |h, part|
214
+ next h if part == ''
215
+ return false unless params_hash_type?(h) && h.key?(part)
216
+ h[part]
217
+ end
218
+
219
+ true
220
+ end
221
+
222
+ def each_query_pair(qs, separator, unescaper = nil)
223
+ return if !qs || qs.empty?
224
+
225
+ if qs.bytesize > @bytesize_limit
226
+ raise QueryLimitError, "total query size exceeds limit (#{@bytesize_limit})"
227
+ end
228
+
229
+ pairs = qs.split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP, @params_limit + 1)
230
+
231
+ if pairs.size > @params_limit
232
+ param_count = pairs.size + pairs.last.count(separator || "&")
233
+ raise QueryLimitError, "total number of query parameters (#{param_count}) exceeds limit (#{@params_limit})"
234
+ end
235
+
236
+ if unescaper
237
+ pairs.each do |p|
238
+ next if p.empty?
239
+ k, v = p.split('=', 2).map!(&unescaper)
240
+ yield k, v
241
+ end
242
+ else
243
+ pairs.each do |p|
244
+ next if p.empty?
245
+ k, v = p.split('=', 2).map! { |s| unescape(s) }
246
+ yield k, v
247
+ end
248
+ end
249
+ rescue ArgumentError => e
250
+ raise InvalidParameterError, e.message, e.backtrace
251
+ end
252
+
253
+ def unescape(string, encoding = Encoding::UTF_8)
254
+ URI.decode_www_form_component(string, encoding)
255
+ end
256
+
257
+ class Params < Hash
258
+ alias_method :to_params_hash, :to_h
259
+ end
260
+ end
261
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ require_relative 'constants'
6
+
7
+ module Rack
8
+ # Rack::ForwardRequest gets caught by Rack::Recursive and redirects
9
+ # the current request to the app at +url+.
10
+ #
11
+ # raise ForwardRequest.new("/not-found")
12
+ #
13
+
14
+ class ForwardRequest < Exception
15
+ attr_reader :url, :env
16
+
17
+ def initialize(url, env = {})
18
+ @url = URI(url)
19
+ @env = env
20
+
21
+ @env[PATH_INFO] = @url.path
22
+ @env[QUERY_STRING] = @url.query if @url.query
23
+ @env[HTTP_HOST] = @url.host if @url.host
24
+ @env[HTTP_PORT] = @url.port if @url.port
25
+ @env[RACK_URL_SCHEME] = @url.scheme if @url.scheme
26
+
27
+ super "forwarding to #{url}"
28
+ end
29
+ end
30
+
31
+ # Rack::Recursive allows applications called down the chain to
32
+ # include data from other applications (by using
33
+ # <tt>rack['rack.recursive.include'][...]</tt> or raise a
34
+ # ForwardRequest to redirect internally.
35
+
36
+ class Recursive
37
+ def initialize(app)
38
+ @app = app
39
+ end
40
+
41
+ def call(env)
42
+ dup._call(env)
43
+ end
44
+
45
+ def _call(env)
46
+ @script_name = env[SCRIPT_NAME]
47
+ @app.call(env.merge(RACK_RECURSIVE_INCLUDE => method(:include)))
48
+ rescue ForwardRequest => req
49
+ call(env.merge(req.env))
50
+ end
51
+
52
+ def include(env, path)
53
+ unless path.index(@script_name) == 0 && (path[@script_name.size] == ?/ ||
54
+ path[@script_name.size].nil?)
55
+ raise ArgumentError, "can only include below #{@script_name}, not #{path}"
56
+ end
57
+
58
+ env = env.merge(PATH_INFO => path,
59
+ SCRIPT_NAME => @script_name,
60
+ REQUEST_METHOD => GET,
61
+ "CONTENT_LENGTH" => "0", "CONTENT_TYPE" => "",
62
+ RACK_INPUT => StringIO.new(""))
63
+ @app.call(env)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,112 @@
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
+ def initialize(app, cooldown = 10, backend = Stat)
26
+ @app = app
27
+ @cooldown = cooldown
28
+ @last = (Time.now - cooldown)
29
+ @cache = {}
30
+ @mtimes = {}
31
+ @reload_mutex = Mutex.new
32
+
33
+ extend backend
34
+ end
35
+
36
+ def call(env)
37
+ if @cooldown and Time.now > @last + @cooldown
38
+ if Thread.list.size > 1
39
+ @reload_mutex.synchronize{ reload! }
40
+ else
41
+ reload!
42
+ end
43
+
44
+ @last = Time.now
45
+ end
46
+
47
+ @app.call(env)
48
+ end
49
+
50
+ def reload!(stderr = $stderr)
51
+ rotation do |file, mtime|
52
+ previous_mtime = @mtimes[file] ||= mtime
53
+ safe_load(file, mtime, stderr) if mtime > previous_mtime
54
+ end
55
+ end
56
+
57
+ # A safe Kernel::load, issuing the hooks depending on the results
58
+ def safe_load(file, mtime, stderr = $stderr)
59
+ load(file)
60
+ stderr.puts "#{self.class}: reloaded `#{file}'"
61
+ file
62
+ rescue LoadError, SyntaxError => ex
63
+ stderr.puts ex
64
+ ensure
65
+ @mtimes[file] = mtime
66
+ end
67
+
68
+ module Stat
69
+ def rotation
70
+ files = [$0, *$LOADED_FEATURES].uniq
71
+ paths = ['./', *$LOAD_PATH].uniq
72
+
73
+ files.map{|file|
74
+ next if /\.(so|bundle)$/.match?(file) # cannot reload compiled files
75
+
76
+ found, stat = figure_path(file, paths)
77
+ next unless found && stat && mtime = stat.mtime
78
+
79
+ @cache[file] = found
80
+
81
+ yield(found, mtime)
82
+ }.compact
83
+ end
84
+
85
+ # Takes a relative or absolute +file+ name, a couple possible +paths+ that
86
+ # the +file+ might reside in. Returns the full path and File::Stat for the
87
+ # path.
88
+ def figure_path(file, paths)
89
+ found = @cache[file]
90
+ found = file if !found and Pathname.new(file).absolute?
91
+ found, stat = safe_stat(found)
92
+ return found, stat if found
93
+
94
+ paths.find do |possible_path|
95
+ path = ::File.join(possible_path, file)
96
+ found, stat = safe_stat(path)
97
+ return ::File.expand_path(found), stat if found
98
+ end
99
+
100
+ return false, false
101
+ end
102
+
103
+ def safe_stat(file)
104
+ return unless file
105
+ stat = ::File.stat(file)
106
+ return file, stat if stat.file?
107
+ rescue Errno::ENOENT, Errno::ENOTDIR, Errno::ESRCH
108
+ @cache.delete(file) and false
109
+ end
110
+ end
111
+ end
112
+ end