homura-runtime 0.3.3 → 0.3.4

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/lib/homura/runtime/version.rb +1 -1
  4. data/vendor/rack/auth/abstract/handler.rb +41 -0
  5. data/vendor/rack/auth/abstract/request.rb +51 -0
  6. data/vendor/rack/auth/basic.rb +58 -0
  7. data/vendor/rack/bad_request.rb +8 -0
  8. data/vendor/rack/body_proxy.rb +63 -0
  9. data/vendor/rack/builder.rb +315 -0
  10. data/vendor/rack/cascade.rb +67 -0
  11. data/vendor/rack/common_logger.rb +94 -0
  12. data/vendor/rack/conditional_get.rb +87 -0
  13. data/vendor/rack/config.rb +22 -0
  14. data/vendor/rack/constants.rb +68 -0
  15. data/vendor/rack/content_length.rb +34 -0
  16. data/vendor/rack/content_type.rb +33 -0
  17. data/vendor/rack/deflater.rb +159 -0
  18. data/vendor/rack/directory.rb +210 -0
  19. data/vendor/rack/etag.rb +71 -0
  20. data/vendor/rack/events.rb +172 -0
  21. data/vendor/rack/files.rb +224 -0
  22. data/vendor/rack/head.rb +25 -0
  23. data/vendor/rack/headers.rb +238 -0
  24. data/vendor/rack/lint.rb +1000 -0
  25. data/vendor/rack/lock.rb +29 -0
  26. data/vendor/rack/media_type.rb +42 -0
  27. data/vendor/rack/method_override.rb +56 -0
  28. data/vendor/rack/mime.rb +694 -0
  29. data/vendor/rack/mock.rb +3 -0
  30. data/vendor/rack/mock_request.rb +161 -0
  31. data/vendor/rack/mock_response.rb +147 -0
  32. data/vendor/rack/multipart/generator.rb +99 -0
  33. data/vendor/rack/multipart/parser.rb +586 -0
  34. data/vendor/rack/multipart/uploaded_file.rb +82 -0
  35. data/vendor/rack/multipart.rb +77 -0
  36. data/vendor/rack/null_logger.rb +48 -0
  37. data/vendor/rack/protection/authenticity_token.rb +256 -0
  38. data/vendor/rack/protection/base.rb +140 -0
  39. data/vendor/rack/protection/content_security_policy.rb +80 -0
  40. data/vendor/rack/protection/cookie_tossing.rb +77 -0
  41. data/vendor/rack/protection/escaped_params.rb +93 -0
  42. data/vendor/rack/protection/form_token.rb +25 -0
  43. data/vendor/rack/protection/frame_options.rb +39 -0
  44. data/vendor/rack/protection/http_origin.rb +43 -0
  45. data/vendor/rack/protection/ip_spoofing.rb +27 -0
  46. data/vendor/rack/protection/json_csrf.rb +60 -0
  47. data/vendor/rack/protection/path_traversal.rb +45 -0
  48. data/vendor/rack/protection/referrer_policy.rb +27 -0
  49. data/vendor/rack/protection/remote_referrer.rb +22 -0
  50. data/vendor/rack/protection/remote_token.rb +24 -0
  51. data/vendor/rack/protection/session_hijacking.rb +37 -0
  52. data/vendor/rack/protection/strict_transport.rb +41 -0
  53. data/vendor/rack/protection/version.rb +7 -0
  54. data/vendor/rack/protection/xss_header.rb +27 -0
  55. data/vendor/rack/protection.rb +58 -0
  56. data/vendor/rack/query_parser.rb +261 -0
  57. data/vendor/rack/recursive.rb +66 -0
  58. data/vendor/rack/reloader.rb +112 -0
  59. data/vendor/rack/request.rb +818 -0
  60. data/vendor/rack/response.rb +403 -0
  61. data/vendor/rack/rewindable_input.rb +116 -0
  62. data/vendor/rack/runtime.rb +35 -0
  63. data/vendor/rack/sendfile.rb +197 -0
  64. data/vendor/rack/session/abstract/id.rb +533 -0
  65. data/vendor/rack/session/constants.rb +13 -0
  66. data/vendor/rack/session/cookie.rb +292 -0
  67. data/vendor/rack/session/encryptor.rb +415 -0
  68. data/vendor/rack/session/pool.rb +76 -0
  69. data/vendor/rack/session/version.rb +10 -0
  70. data/vendor/rack/session.rb +12 -0
  71. data/vendor/rack/show_exceptions.rb +433 -0
  72. data/vendor/rack/show_status.rb +121 -0
  73. data/vendor/rack/static.rb +188 -0
  74. data/vendor/rack/tempfile_reaper.rb +44 -0
  75. data/vendor/rack/urlmap.rb +99 -0
  76. data/vendor/rack/utils.rb +631 -0
  77. data/vendor/rack/version.rb +17 -0
  78. data/vendor/rack.rb +66 -0
  79. metadata +76 -1
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'mock_request'
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'stringio'
5
+
6
+ require_relative 'constants'
7
+ require_relative 'mock_response'
8
+
9
+ module Rack
10
+ # Rack::MockRequest helps testing your Rack application without
11
+ # actually using HTTP.
12
+ #
13
+ # After performing a request on a URL with get/post/put/patch/delete, it
14
+ # returns a MockResponse with useful helper methods for effective
15
+ # testing.
16
+ #
17
+ # You can pass a hash with additional configuration to the
18
+ # get/post/put/patch/delete.
19
+ # <tt>:input</tt>:: A String or IO-like to be used as rack.input.
20
+ # <tt>:fatal</tt>:: Raise a FatalWarning if the app writes to rack.errors.
21
+ # <tt>:lint</tt>:: If true, wrap the application in a Rack::Lint.
22
+
23
+ class MockRequest
24
+ class FatalWarning < RuntimeError
25
+ end
26
+
27
+ class FatalWarner
28
+ def puts(warning)
29
+ raise FatalWarning, warning
30
+ end
31
+
32
+ def write(warning)
33
+ raise FatalWarning, warning
34
+ end
35
+
36
+ def flush
37
+ end
38
+
39
+ def string
40
+ ""
41
+ end
42
+ end
43
+
44
+ def initialize(app)
45
+ @app = app
46
+ end
47
+
48
+ # Make a GET request and return a MockResponse. See #request.
49
+ def get(uri, opts = {}) request(GET, uri, opts) end
50
+ # Make a POST request and return a MockResponse. See #request.
51
+ def post(uri, opts = {}) request(POST, uri, opts) end
52
+ # Make a PUT request and return a MockResponse. See #request.
53
+ def put(uri, opts = {}) request(PUT, uri, opts) end
54
+ # Make a PATCH request and return a MockResponse. See #request.
55
+ def patch(uri, opts = {}) request(PATCH, uri, opts) end
56
+ # Make a DELETE request and return a MockResponse. See #request.
57
+ def delete(uri, opts = {}) request(DELETE, uri, opts) end
58
+ # Make a HEAD request and return a MockResponse. See #request.
59
+ def head(uri, opts = {}) request(HEAD, uri, opts) end
60
+ # Make an OPTIONS request and return a MockResponse. See #request.
61
+ def options(uri, opts = {}) request(OPTIONS, uri, opts) end
62
+
63
+ # Make a request using the given request method for the given
64
+ # uri to the rack application and return a MockResponse.
65
+ # Options given are passed to MockRequest.env_for.
66
+ def request(method = GET, uri = "", opts = {})
67
+ env = self.class.env_for(uri, opts.merge(method: method))
68
+
69
+ if opts[:lint]
70
+ app = Rack::Lint.new(@app)
71
+ else
72
+ app = @app
73
+ end
74
+
75
+ errors = env[RACK_ERRORS]
76
+ status, headers, body = app.call(env)
77
+ MockResponse.new(status, headers, body, errors)
78
+ ensure
79
+ body.close if body.respond_to?(:close)
80
+ end
81
+
82
+ # For historical reasons, we're pinning to RFC 2396.
83
+ # URI::Parser = URI::RFC2396_Parser
84
+ def self.parse_uri_rfc2396(uri)
85
+ @parser ||= URI::Parser.new
86
+ @parser.parse(uri)
87
+ end
88
+
89
+ # Return the Rack environment used for a request to +uri+.
90
+ # All options that are strings are added to the returned environment.
91
+ # Options:
92
+ # :fatal :: Whether to raise an exception if request outputs to rack.errors
93
+ # :input :: The rack.input to set
94
+ # :http_version :: The SERVER_PROTOCOL to set
95
+ # :method :: The HTTP request method to use
96
+ # :params :: The params to use
97
+ # :script_name :: The SCRIPT_NAME to set
98
+ def self.env_for(uri = "", opts = {})
99
+ uri = parse_uri_rfc2396(uri)
100
+ uri.path = "/#{uri.path}" unless uri.path[0] == ?/
101
+
102
+ env = {}
103
+
104
+ env[REQUEST_METHOD] = (opts[:method] ? opts[:method].to_s.upcase : GET).b
105
+ env[SERVER_NAME] = (uri.host || "example.org").b
106
+ env[SERVER_PORT] = (uri.port ? uri.port.to_s : "80").b
107
+ env[SERVER_PROTOCOL] = opts[:http_version] || 'HTTP/1.1'
108
+ env[QUERY_STRING] = (uri.query.to_s).b
109
+ env[PATH_INFO] = (uri.path).b
110
+ env[RACK_URL_SCHEME] = (uri.scheme || "http").b
111
+ env[HTTPS] = (env[RACK_URL_SCHEME] == "https" ? "on" : "off").b
112
+
113
+ env[SCRIPT_NAME] = opts[:script_name] || ""
114
+
115
+ if opts[:fatal]
116
+ env[RACK_ERRORS] = FatalWarner.new
117
+ else
118
+ env[RACK_ERRORS] = StringIO.new
119
+ end
120
+
121
+ if params = opts[:params]
122
+ if env[REQUEST_METHOD] == GET
123
+ params = Utils.parse_nested_query(params) if params.is_a?(String)
124
+ params.update(Utils.parse_nested_query(env[QUERY_STRING]))
125
+ env[QUERY_STRING] = Utils.build_nested_query(params)
126
+ elsif !opts.has_key?(:input)
127
+ opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
128
+ if params.is_a?(Hash)
129
+ if data = Rack::Multipart.build_multipart(params)
130
+ opts[:input] = data
131
+ opts["CONTENT_LENGTH"] ||= data.length.to_s
132
+ opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{Rack::Multipart::MULTIPART_BOUNDARY}"
133
+ else
134
+ opts[:input] = Utils.build_nested_query(params)
135
+ end
136
+ else
137
+ opts[:input] = params
138
+ end
139
+ end
140
+ end
141
+
142
+ rack_input = opts[:input]
143
+ if String === rack_input
144
+ rack_input = StringIO.new(rack_input)
145
+ end
146
+
147
+ if rack_input
148
+ rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
149
+ env[RACK_INPUT] = rack_input
150
+
151
+ env["CONTENT_LENGTH"] ||= env[RACK_INPUT].size.to_s if env[RACK_INPUT].respond_to?(:size)
152
+ end
153
+
154
+ opts.each { |field, value|
155
+ env[field] = value if String === field
156
+ }
157
+
158
+ env
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ require_relative 'response'
6
+
7
+ module Rack
8
+ # Rack::MockResponse provides useful helpers for testing your apps.
9
+ # Usually, you don't create the MockResponse on your own, but use
10
+ # MockRequest.
11
+
12
+ class MockResponse < Rack::Response
13
+ class Cookie
14
+ attr_reader :name, :value, :path, :domain, :expires, :secure
15
+
16
+ def initialize(args)
17
+ @name = args["name"]
18
+ @value = args["value"]
19
+ @path = args["path"]
20
+ @domain = args["domain"]
21
+ @expires = args["expires"]
22
+ @secure = args["secure"]
23
+ end
24
+
25
+ def method_missing(method_name, *args, &block)
26
+ @value.send(method_name, *args, &block)
27
+ end
28
+ # :nocov:
29
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
30
+ # :nocov:
31
+
32
+ def respond_to_missing?(method_name, include_all = false)
33
+ @value.respond_to?(method_name, include_all) || super
34
+ end
35
+ end
36
+
37
+ class << self
38
+ alias [] new
39
+ end
40
+
41
+ # Headers
42
+ attr_reader :original_headers, :cookies
43
+
44
+ # Errors
45
+ attr_accessor :errors
46
+
47
+ def initialize(status, headers, body, errors = nil)
48
+ @original_headers = headers
49
+
50
+ if errors
51
+ @errors = errors.string if errors.respond_to?(:string)
52
+ else
53
+ @errors = ""
54
+ end
55
+
56
+ super(body, status, headers)
57
+
58
+ @cookies = parse_cookies_from_header
59
+ buffered_body!
60
+ end
61
+
62
+ def =~(other)
63
+ body =~ other
64
+ end
65
+
66
+ def match(other)
67
+ body.match other
68
+ end
69
+
70
+ def body
71
+ return @buffered_body if defined?(@buffered_body)
72
+
73
+ # FIXME: apparently users of MockResponse expect the return value of
74
+ # MockResponse#body to be a string. However, the real response object
75
+ # returns the body as a list.
76
+ #
77
+ # See spec_showstatus.rb:
78
+ #
79
+ # should "not replace existing messages" do
80
+ # ...
81
+ # res.body.should == "foo!"
82
+ # end
83
+ buffer = @buffered_body = String.new
84
+
85
+ @body.each do |chunk|
86
+ buffer << chunk
87
+ end
88
+
89
+ return buffer
90
+ end
91
+
92
+ def empty?
93
+ [201, 204, 304].include? status
94
+ end
95
+
96
+ def cookie(name)
97
+ cookies.fetch(name, nil)
98
+ end
99
+
100
+ private
101
+
102
+ def parse_cookies_from_header
103
+ cookies = Hash.new
104
+ set_cookie_header = headers['set-cookie']
105
+ if set_cookie_header && !set_cookie_header.empty?
106
+ Array(set_cookie_header).each do |cookie|
107
+ cookie_name, cookie_filling = cookie.split('=', 2)
108
+ cookie_attributes = identify_cookie_attributes cookie_filling
109
+ parsed_cookie = Cookie.new(
110
+ 'name' => cookie_name.strip,
111
+ 'value' => cookie_attributes.fetch('value'),
112
+ 'path' => cookie_attributes.fetch('path', nil),
113
+ 'domain' => cookie_attributes.fetch('domain', nil),
114
+ 'expires' => cookie_attributes.fetch('expires', nil),
115
+ 'secure' => cookie_attributes.fetch('secure', false)
116
+ )
117
+ cookies.store(cookie_name, parsed_cookie)
118
+ end
119
+ end
120
+ cookies
121
+ end
122
+
123
+ def identify_cookie_attributes(cookie_filling)
124
+ cookie_bits = cookie_filling.split(';')
125
+ cookie_attributes = Hash.new
126
+ cookie_attributes.store('value', Array(cookie_bits[0].strip))
127
+ cookie_bits.drop(1).each do |bit|
128
+ if bit.include? '='
129
+ cookie_attribute, attribute_value = bit.split('=', 2)
130
+ cookie_attributes.store(cookie_attribute.strip.downcase, attribute_value.strip)
131
+ end
132
+ if bit.include? 'secure'
133
+ cookie_attributes.store('secure', true)
134
+ end
135
+ end
136
+
137
+ if cookie_attributes.key? 'max-age'
138
+ cookie_attributes.store('expires', Time.now + cookie_attributes['max-age'].to_i)
139
+ elsif cookie_attributes.key? 'expires'
140
+ cookie_attributes.store('expires', Time.httpdate(cookie_attributes['expires']))
141
+ end
142
+
143
+ cookie_attributes
144
+ end
145
+
146
+ end
147
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'uploaded_file'
4
+
5
+ module Rack
6
+ module Multipart
7
+ class Generator
8
+ def initialize(params, first = true)
9
+ @params, @first = params, first
10
+
11
+ if @first && !@params.is_a?(Hash)
12
+ raise ArgumentError, "value must be a Hash"
13
+ end
14
+ end
15
+
16
+ def dump
17
+ return nil if @first && !multipart?
18
+ return flattened_params unless @first
19
+
20
+ flattened_params.map do |name, file|
21
+ if file.respond_to?(:original_filename)
22
+ if file.path
23
+ ::File.open(file.path, 'rb') do |f|
24
+ f.set_encoding(Encoding::BINARY)
25
+ content_for_tempfile(f, file, name)
26
+ end
27
+ else
28
+ content_for_tempfile(file, file, name)
29
+ end
30
+ else
31
+ content_for_other(file, name)
32
+ end
33
+ end.join << "--#{MULTIPART_BOUNDARY}--\r"
34
+ end
35
+
36
+ private
37
+ def multipart?
38
+ query = lambda { |value|
39
+ case value
40
+ when Array
41
+ value.any?(&query)
42
+ when Hash
43
+ value.values.any?(&query)
44
+ when Rack::Multipart::UploadedFile
45
+ true
46
+ end
47
+ }
48
+
49
+ @params.values.any?(&query)
50
+ end
51
+
52
+ def flattened_params
53
+ @flattened_params ||= begin
54
+ h = Hash.new
55
+ @params.each do |key, value|
56
+ k = @first ? key.to_s : "[#{key}]"
57
+
58
+ case value
59
+ when Array
60
+ value.map { |v|
61
+ Multipart.build_multipart(v, false).each { |subkey, subvalue|
62
+ h["#{k}[]#{subkey}"] = subvalue
63
+ }
64
+ }
65
+ when Hash
66
+ Multipart.build_multipart(value, false).each { |subkey, subvalue|
67
+ h[k + subkey] = subvalue
68
+ }
69
+ else
70
+ h[k] = value
71
+ end
72
+ end
73
+ h
74
+ end
75
+ end
76
+
77
+ def content_for_tempfile(io, file, name)
78
+ length = ::File.stat(file.path).size if file.path
79
+ filename = "; filename=\"#{Utils.escape_path(file.original_filename)}\""
80
+ <<-EOF
81
+ --#{MULTIPART_BOUNDARY}\r
82
+ content-disposition: form-data; name="#{name}"#{filename}\r
83
+ content-type: #{file.content_type}\r
84
+ #{"content-length: #{length}\r\n" if length}\r
85
+ #{io.read}\r
86
+ EOF
87
+ end
88
+
89
+ def content_for_other(file, name)
90
+ <<-EOF
91
+ --#{MULTIPART_BOUNDARY}\r
92
+ content-disposition: form-data; name="#{name}"\r
93
+ \r
94
+ #{file}\r
95
+ EOF
96
+ end
97
+ end
98
+ end
99
+ end