Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,12 @@ def inject(carrier, context: Context.current, setter: Context::Propagation.text_
def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter)
header = getter.get(carrier, BAGGAGE_KEY)
return context if header.nil? || header.empty?
return context if header.bytesize > MAX_TOTAL_LENGTH

entries = header.gsub(/\s/, '').split(',')

OpenTelemetry::Baggage.build(context: context) do |builder|
entries.each do |entry|
# Note metadata is currently unused in OpenTelemetry, but is part
# the W3C spec where it's referred to as properties. We preserve
# the properties (as-is) so that they can be propagated elsewhere.
kv, meta = entry.split(';', 2)
k, v = kv.split('=').map!(&URI.method(:decode_uri_component))
builder.set_value(k, v, metadata: meta)
end
decode_entries(entries, builder)
end
rescue StandardError => e
OpenTelemetry.logger.debug "Error extracting W3C baggage: #{e.message}"
Expand All @@ -82,6 +76,22 @@ def fields

private

def decode_entries(entries, builder)
decoded_count = 0
entries.each do |entry|
break if decoded_count >= MAX_ENTRIES
next if entry.bytesize > MAX_ENTRY_LENGTH

# Note metadata is currently unused in OpenTelemetry, but is part
# the W3C spec where it's referred to as properties. We preserve
# the properties (as-is) so that they can be propagated elsewhere.
kv, meta = entry.split(';', 2)
k, v = kv.split('=').map!(&URI.method(:decode_uri_component))
builder.set_value(k, v, metadata: meta)
decoded_count += 1
end
end

def encode(baggage)
result = +''
encoded_count = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,41 @@
_(context.object_id).wont_equal(empty_context.object_id)
end
end

describe 'limits mirroring #inject' do
it 'returns the same context object when the header exceeds the total length of 8192 bytes' do
header = (['k=' + ('v' * 96)] * 100).join(',')
_(header.bytesize).must_be :>, 8192
carrier = { header_key => header }
empty_context = Context.empty
context = propagator.extract(carrier, context: empty_context)
_(context.object_id).must_equal(empty_context.object_id)
end

it 'enforces max of 180 entries on extract' do
header = (0..199).map { |i| "k#{i}=v#{i}" }.join(',')
carrier = { header_key => header }
context = propagator.extract(carrier, context: Context.empty)
entries = OpenTelemetry::Baggage.raw_entries(context: context)
_(entries.size).must_equal(180)
_(entries['k0']).wont_be_nil
_(entries['k179']).wont_be_nil
_(entries['k180']).must_be_nil
_(entries['k199']).must_be_nil
end

it 'skips entries whose size exceeds the max entry length of 4096 bytes' do
oversize_value = 'v' * 4096
header = "big=#{oversize_value},key2=val2"
_(header.bytesize).must_be :<=, 8192
carrier = { header_key => header }
context = propagator.extract(carrier, context: Context.empty)
entries = OpenTelemetry::Baggage.raw_entries(context: context)
_(entries['big']).must_be_nil
_(entries['key2']).wont_be_nil
_(entries['key2'].value).must_equal('val2')
end
end
end

describe '#inject' do
Expand Down
Loading