1
0
mirror of https://github.com/meineerde/rackstash.git synced 2025-10-17 14:01:01 +00:00

Be more strict when parsing URIs for adapter creation

We require correct case of the schema and we no longer use the opaque
part (which appears to have been a bug anyways at this place)
This commit is contained in:
Holger Just 2020-07-17 17:30:00 +02:00
parent 0e0cb7dbae
commit 65bf5ae252
2 changed files with 25 additions and 23 deletions

View File

@ -15,17 +15,17 @@ module Rackstash
# log target, ...). With the provided `matchers`, a class can describe
# which kind of log devices are suitable to be used with it:
#
# * `String` with only lower-case characters - When passing a string with
# only lower-case characters, we register it as the scheme of a URL.
# When retrieving an adapter for a URL in {[]}, we check if the URL's
# scheme matches this string.
# * `String` with other characters - When passing a string that doesn't
# look like a URL scheme, we assume it to represent a class name. When
# * `String` as class name - When passing a string that starts with an
# uper-case character, we assume it to represent a class name. When
# retrieving a matching adapter for a device, we check if the name of
# the device's class matches this string. This can be used to register
# an adapter for a device which might not be loaded (yet), e.g. from an
# external gem. If possible, you should register the adapter for the
# actual class instead of its name.
# * `String` as URI scheme - When passing a string that doesn't start with
# an uper-case character, we register it as the scheme of a URI. When
# retrieving an adapter for a URI in {[]}, we check if the URI's scheme
# matches this string.
# * `Symbol` - When passing a symbol, we check if the resolved device
# responds to an equally named method.
# * An object responding to the `===` method - When retrieving an adapter
@ -53,25 +53,27 @@ module Rackstash
case matcher
when String
matcher = matcher.to_s
if matcher =~ /\A[a-z0-9]/
# If the matcher is a lower-case string, we assume it is a URL
# scheme.
adapter_schemes[matcher.downcase] = adapter_class
else
# If it starts with a upper-case characters, we assume it is a
# class name.
if matcher =~ /\A[A-Z]/
# If the matcher starts with a upper-case characters, we assume it
# is a class name.
# Since we use `compare_by_identity` for types, we need to ensure
# that we can override existing class names.
adapter_types.delete_if { |key, _value| key == matcher }
adapter_types[matcher] = adapter_class
elsif !matcher.empty?
# If the matcher is a lower-case string, we assume it is a URL
# scheme.
adapter_schemes[matcher] = adapter_class
else
raise TypeError, "invalid matcher: #{matcher}"
end
when Symbol, ->(o) { o.respond_to?(:===) }
adapter_types[matcher] = adapter_class
else
# Should not be reached by "normal" objects since `Object` already
# responds to `===` (which is the same as `==` by default)
raise TypeError, "unknown matcher: #{matcher.inspect}"
raise TypeError, "invalid matcher: #{matcher}"
end
end
@ -94,7 +96,7 @@ module Rackstash
def [](device)
return device if device.is_a?(BaseAdapter)
adapter = adapter_by_uri(device)
adapter = adapter_by_uri_scheme(device)
adapter ||= adapter_by_type(device)
unless adapter
@ -105,12 +107,11 @@ module Rackstash
private
def adapter_by_uri(uri)
def adapter_by_uri_scheme(uri)
uri = URI(uri) rescue return
scheme = uri.scheme || uri.opaque
return unless uri.scheme
return unless scheme
adapter_class = adapter_schemes.fetch(scheme.to_s.downcase) {
adapter_class = adapter_schemes.fetch(uri.scheme) {
raise ArgumentError, "No log adapter found for URI #{uri}"
}

View File

@ -45,11 +45,9 @@ RSpec.describe Rackstash::Adapter do
it 'can register a class name (upper-case String)' do
expect {
described_class.register adapter, '❤'
described_class.register adapter, ''
described_class.register adapter, 'Hello::World'
}.to change { described_class.send(:adapter_types).size }
.from(0).to(3)
.from(0).to(1)
# Registering 'Hello::World' a second time overwrites the first one
expect {
@ -79,8 +77,9 @@ RSpec.describe Rackstash::Adapter do
it 'can register a scheme (lower-case String)' do
expect {
described_class.register adapter, 'customscheme'
described_class.register adapter, '❤'
}.to change { described_class.send(:adapter_schemes).size }
.from(0).to(1)
.from(0).to(2)
expect(described_class.send(:adapter_types).size).to eql 0
end
@ -99,6 +98,8 @@ RSpec.describe Rackstash::Adapter do
expect { described_class.register(adapter, matcher) }
.to raise_error(TypeError)
expect { described_class.register(adapter, '') }
.to raise_error(TypeError)
end
end