Skip to content
Merged
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
42 changes: 42 additions & 0 deletions src/OpenTelemetry.Extensions.Propagators/JaegerPropagator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#if NET
using System.Buffers;
#endif
using System.Diagnostics;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Internal;
Expand All @@ -25,6 +28,10 @@ public class JaegerPropagator : TextMapPropagator
private static readonly int TraceId128BitLength = "0af7651916cd43dd8448eb211c80319c".Length;
private static readonly int SpanIdLength = "00f067aa0ba902b7".Length;

#if NET
private static readonly SearchValues<char> DelimiterHintChars = SearchValues.Create(":%");
#endif

/// <inheritdoc/>
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member
public override ISet<string> Fields => new HashSet<string> { JaegerHeader };
Expand Down Expand Up @@ -236,6 +243,40 @@ private static bool TryExtractTraceParts(

private static ReadOnlySpan<char> ReadNextComponent(string header, ref int position)
{
#if NET
var remaining = header.AsSpan(position);
var scanOffset = 0;
while (true)
{
var delimiterIndex = remaining.Slice(scanOffset).IndexOfAny(DelimiterHintChars);
if (delimiterIndex < 0)
{
var result = remaining;
position = header.Length;
return result;
}

delimiterIndex += scanOffset;

if (remaining[delimiterIndex] == ':')
{
var component = remaining.Slice(0, delimiterIndex);
position += delimiterIndex + 1;
return component;
}

if (remaining.Length - delimiterIndex >= JaegerDelimiterEncoded.Length &&
remaining[delimiterIndex + 1] == '3' &&
remaining[delimiterIndex + 2] == 'A')
{
var component = remaining.Slice(0, delimiterIndex);
position += delimiterIndex + JaegerDelimiterEncoded.Length;
return component;
}

scanOffset = delimiterIndex + 1;
}
Comment thread
martincostello marked this conversation as resolved.
#else
var colonIndex = header.IndexOf(JaegerDelimiter, position, StringComparison.Ordinal);
var encodedIndex = header.IndexOf(JaegerDelimiterEncoded, position, StringComparison.Ordinal);

Expand Down Expand Up @@ -263,5 +304,6 @@ private static ReadOnlySpan<char> ReadNextComponent(string header, ref int posit
var component = header.AsSpan(position, nextIndex - position);
position = nextIndex + delimiterLength;
return component;
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,20 @@ public void ExtractReturnsNewContextIfHeaderContainsEmptyComponent()
Assert.Equal(ActivityTraceFlags.Recorded, result.ActivityContext.TraceFlags);
}

[Fact]
public void ExtractReturnsOriginalContextIfHeaderContainsUnexpectedPercentCharacter()
{
var formattedHeader = $"%{TraceId}{JaegerDelimiter}{SpanId}{JaegerDelimiter}{ParentSpanId}{JaegerDelimiter}{FlagSampled}";
var headers = new Dictionary<string, string[]>
{
[JaegerHeader] = [formattedHeader],
};

var result = new JaegerPropagator().Extract(default, headers, Getter);

Assert.Equal(default, result);
}

[Fact]
public void InjectDoesNoopIfContextIsInvalid()
{
Expand Down
Loading