openapi_first 4.0.1 → 4.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/openapi_first/builder.rb +3 -3
- data/lib/openapi_first/parameters_parser.rb +14 -2
- data/lib/openapi_first/query_string_parser.rb +14 -2
- data/lib/openapi_first/request.rb +10 -1
- data/lib/openapi_first/response_parser.rb +1 -1
- data/lib/openapi_first/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac70785f7221fecd32d0a1408c8c12ee14ea75f5d45be6c9c1efce38e735d02e
|
|
4
|
+
data.tar.gz: 0cea3e400f9eed814fc9924c551893d78444920d99f7573d59426a7fa7a61068
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c8883be1aad4a502ac4596ecb91765b855e2d515ec3e6ad11519a350ed43f29ae591645b71f7f7da709775cd1322c9dd4803f1474032bf5e8004abfd4b0eb51
|
|
7
|
+
data.tar.gz: 21e78cbcc5607436c1a32e108f786b0ddfc7ad434d2d103cee6f506eb90bef74d6dfcc4977ce748b612aeeab0c9e50c3a372c77da66a291275ead799bf677226
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 4.1.0
|
|
6
|
+
|
|
7
|
+
- Query and cookie parameter values with invalid encoding (like `?search=%C3`) produce a 400 response now. Before such a value passed validation or raised an `ArgumentError`. This applies to documented and undocumented query parameter, but only to documented cookie parameters.
|
|
8
|
+
- A query string with more parameters than Rack accepts (4096 by default) produces a 400 response now instead of raising `Rack::QueryParser::QueryLimitError`. See the [rack documentation](https://rack.github.io/rack/main/index.html#configuration) about how to configure this.
|
|
9
|
+
|
|
5
10
|
## 4.0.1
|
|
6
11
|
|
|
7
12
|
- Fix: Reduced memory usage with large API descriptions. Schemas no longer each deep-copy (stringify keys) the whole OAD to build a root schema. This is a json_schemer specific optimization.
|
|
@@ -126,10 +126,10 @@ module OpenapiFirst
|
|
|
126
126
|
cookie = build_parameters(grouped[:cookie])
|
|
127
127
|
ParsedParameters.new(
|
|
128
128
|
all: [*path, *query, *header, *cookie].freeze,
|
|
129
|
-
path_parser: grouped[:path] && ParametersParser.new(path),
|
|
129
|
+
path_parser: grouped[:path] && ParametersParser.new(path, check_encoding: false),
|
|
130
130
|
query_parser: QueryStringParser.new(query),
|
|
131
|
-
header_parser: grouped[:header] && ParametersParser.new(header),
|
|
132
|
-
cookie_parser: grouped[:cookie] && ParametersParser.new(cookie),
|
|
131
|
+
header_parser: grouped[:header] && ParametersParser.new(header, check_encoding: false),
|
|
132
|
+
cookie_parser: grouped[:cookie] && ParametersParser.new(cookie, check_encoding: true),
|
|
133
133
|
path_schema: build_parameter_schema(grouped[:path]),
|
|
134
134
|
query_schema: build_parameter_schema(grouped[:query]),
|
|
135
135
|
header_schema: build_parameter_schema(grouped[:header]),
|
|
@@ -5,8 +5,10 @@ module OpenapiFirst
|
|
|
5
5
|
# @visibility private
|
|
6
6
|
class ParametersParser
|
|
7
7
|
# @param parameters [Array<Parameter>]
|
|
8
|
-
|
|
8
|
+
# @param check_encoding [Boolean] Raise Rack::Utils::InvalidParameterError if a value has an invalid encoding.
|
|
9
|
+
def initialize(parameters, check_encoding:)
|
|
9
10
|
@parameters = parameters
|
|
11
|
+
@check_encoding = check_encoding
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
attr_reader :parameters
|
|
@@ -16,8 +18,18 @@ module OpenapiFirst
|
|
|
16
18
|
parameters.each_with_object({}) do |parameter, result|
|
|
17
19
|
next unless parameters_hash.key?(parameter.name)
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
value = parameters_hash[parameter.name]
|
|
22
|
+
check_encoding!(value) if @check_encoding
|
|
23
|
+
result[parameter.name] = parameter.unpack_and_convert(value)
|
|
20
24
|
end
|
|
21
25
|
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def check_encoding!(value)
|
|
30
|
+
return if !value.is_a?(::String) || value.valid_encoding?
|
|
31
|
+
|
|
32
|
+
raise Rack::Utils::InvalidParameterError, "invalid encoding (#{value.inspect})"
|
|
33
|
+
end
|
|
22
34
|
end
|
|
23
35
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'rack'
|
|
4
|
+
require 'rack/query_parser'
|
|
4
5
|
require_relative 'parameters_parser'
|
|
5
6
|
|
|
6
7
|
module OpenapiFirst
|
|
@@ -10,11 +11,15 @@ module OpenapiFirst
|
|
|
10
11
|
DEEP_PROP = '\[([\w-]+)\]$'
|
|
11
12
|
private_constant :DEEP_PROP
|
|
12
13
|
|
|
14
|
+
# Rack < 3.1 does not know about Rack::BadRequest
|
|
15
|
+
BAD_REQUEST = defined?(Rack::BadRequest) ? Rack::BadRequest : Rack::QueryParser::QueryLimitError
|
|
16
|
+
private_constant :BAD_REQUEST
|
|
17
|
+
|
|
13
18
|
# @param parameters [Array<Parameter>]
|
|
14
19
|
def initialize(parameters)
|
|
15
20
|
@parameters = parameters
|
|
16
21
|
@deep_object_parameters, flat_parameters = parameters.partition(&:deep_object?)
|
|
17
|
-
@flat_parser = ParametersParser.new(flat_parameters)
|
|
22
|
+
@flat_parser = ParametersParser.new(flat_parameters, check_encoding: false)
|
|
18
23
|
@deep_object_properties = {}
|
|
19
24
|
@deep_object_regex = {}
|
|
20
25
|
@deep_object_parameters.each do |parameter|
|
|
@@ -54,16 +59,23 @@ module OpenapiFirst
|
|
|
54
59
|
return if unknown.empty?
|
|
55
60
|
|
|
56
61
|
unknown
|
|
62
|
+
rescue Rack::Utils::InvalidParameterError
|
|
63
|
+
nil
|
|
57
64
|
end
|
|
58
65
|
|
|
59
66
|
private
|
|
60
67
|
|
|
61
68
|
def parse_query(query_string)
|
|
62
69
|
Rack::Utils.parse_query(query_string) do |string|
|
|
63
|
-
Rack::Utils.unescape(string)
|
|
70
|
+
unescaped = Rack::Utils.unescape(string)
|
|
71
|
+
next unescaped if unescaped.valid_encoding?
|
|
72
|
+
|
|
73
|
+
raise Rack::Utils::InvalidParameterError, "invalid encoding (#{string})"
|
|
64
74
|
rescue ArgumentError => e
|
|
65
75
|
raise Rack::Utils::InvalidParameterError, e.message
|
|
66
76
|
end
|
|
77
|
+
rescue BAD_REQUEST => e
|
|
78
|
+
raise Rack::Utils::InvalidParameterError, e.message
|
|
67
79
|
end
|
|
68
80
|
|
|
69
81
|
def parse_deep_object(parameter, parsed_query)
|
|
@@ -61,6 +61,9 @@ module OpenapiFirst
|
|
|
61
61
|
query, query_error = parse_query(request.env[Rack::QUERY_STRING])
|
|
62
62
|
return [nil, query_error] if query_error
|
|
63
63
|
|
|
64
|
+
cookies = parse_cookies(request.env[Rack::HTTP_COOKIE])
|
|
65
|
+
return [nil, cookies] if cookies.is_a?(Failure)
|
|
66
|
+
|
|
64
67
|
body = @body_parsers&.call(request)
|
|
65
68
|
return [nil, body] if body.is_a?(Failure)
|
|
66
69
|
|
|
@@ -68,7 +71,7 @@ module OpenapiFirst
|
|
|
68
71
|
path: @path_parser&.unpack(route_params),
|
|
69
72
|
query:,
|
|
70
73
|
headers: @header_parser&.unpack(RequestHeaders.new(request.env)),
|
|
71
|
-
cookies
|
|
74
|
+
cookies:,
|
|
72
75
|
body:
|
|
73
76
|
), nil]
|
|
74
77
|
end
|
|
@@ -79,6 +82,12 @@ module OpenapiFirst
|
|
|
79
82
|
[nil, Failure.new(:invalid_query, message: 'Invalid query parameter.')]
|
|
80
83
|
end
|
|
81
84
|
|
|
85
|
+
def parse_cookies(cookie_header)
|
|
86
|
+
@cookie_parser&.unpack(Rack::Utils.parse_cookies_header(cookie_header))
|
|
87
|
+
rescue Rack::Utils::InvalidParameterError
|
|
88
|
+
Failure.new(:invalid_cookie, message: 'Invalid cookie value.')
|
|
89
|
+
end
|
|
90
|
+
|
|
82
91
|
def build_body_parser(content_type, encoding)
|
|
83
92
|
RequestBodyParsers[content_type, { encoding: encoding || {} }]
|
|
84
93
|
end
|