Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix space trimming and baggage order
  • Loading branch information
tarekgh committed Jun 23, 2021
commit 7f4ebc5c06895254bc3e56f3c95c1ef39f85a52d
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public abstract class TextMapPropagator
public abstract bool Extract(object carrier, PropagatorGetterCallback getter, out string? id, out string? state);
public abstract bool Extract(object carrier, PropagatorGetterCallback getter, out System.Diagnostics.ActivityContext context);
public abstract bool Extract(object carrier, PropagatorGetterCallback getter, out System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string?>>? baggage);
public static TextMapPropagator DefaultPropagator { get; set; }
public static TextMapPropagator Default { get; set; }
public static TextMapPropagator CreateLegacyPropagator() { throw null; }
public static TextMapPropagator CreatePassThroughPropagator() { throw null; }
public static TextMapPropagator CreateOutputSuppressionPropagator() { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public abstract class TextMapPropagator
// Static APIs
//

public static TextMapPropagator DefaultPropagator { get; set; } = CreateLegacyPropagator();
public static TextMapPropagator Default { get; set; } = CreateLegacyPropagator();

// For Microsoft compatibility. e.g., it will propagate Baggage header name as "Correlation-Context" instead of "baggage".
public static TextMapPropagator CreateLegacyPropagator() => new LegacyTextMapPropagator();
Expand All @@ -47,15 +47,22 @@ public abstract class TextMapPropagator
// Internal
//

internal const char Space = ' ';
internal const char Tab = (char)9;
internal const char Comma = ',';
internal const char Semicolon = ';';

internal const int MaxBaggageLength = 8192;
internal const int MaxKeyValueLength = 4096;
internal const int MaxBaggageItems = 180;

internal const string TraceParent = "traceparent";
internal const string RequestId = "Request-Id";
internal const string TraceState = "tracestate";
internal const string Baggage = "baggage";
internal const string CorrelationContext = "Correlation-Context";
internal static readonly char[] EqualSignSeparator = new[] { '=' };
internal static readonly char[] CommaSignSeparator = new[] { ',' };
internal const int MaxBaggageLength = 8192;
internal const int MaxBaggageItems = 180;

internal static readonly char [] s_trimmingSpaceCharacters = new char[] { Space, Tab };

internal static void InjectBaggage(object carrier, IEnumerable<KeyValuePair<string, string?>> baggage, Action<object /* carrier */, string /* field name */, string /* value to inject */> setter, bool injectAsW3C = false)
{
Expand All @@ -67,7 +74,7 @@ internal static void InjectBaggage(object carrier, IEnumerable<KeyValuePair<stri
do
{
KeyValuePair<string, string?> item = e.Current;
baggageList.Append(WebUtility.UrlEncode(item.Key)).Append('=').Append(WebUtility.UrlEncode(item.Value)).Append(',');
baggageList.Append(WebUtility.UrlEncode(item.Key)).Append('=').Append(WebUtility.UrlEncode(item.Value)).Append(Comma);
}
while (e.MoveNext());
baggageList.Remove(baggageList.Length - 1, 1);
Expand All @@ -87,41 +94,79 @@ internal static bool TryExtractBaggage(string baggagestring, out IEnumerable<Key
return true;
}

foreach (string pair in baggagestring.Split(CommaSignSeparator))
int currentIndex = 0;

do
{
baggageLength += pair.Length + 1; // pair and comma
// Skip spaces
while (currentIndex < baggagestring.Length && (baggagestring[currentIndex] == Space || baggagestring[currentIndex] == Tab)) { currentIndex++; }

if (baggageLength >= MaxBaggageLength || baggageList?.Count >= MaxBaggageItems)
{
break;
}
if (currentIndex >= baggagestring.Length) { break; } // No Key exist

if (pair.IndexOf('=') < 0)
{
continue;
}
int keyStart = currentIndex;

var parts = pair.Split(EqualSignSeparator, 2);
if (parts.Length != 2)
{
continue;
}
// Search end of the key
while (currentIndex < baggagestring.Length && baggagestring[currentIndex] != Space && baggagestring[currentIndex] != Tab && baggagestring[currentIndex] != '=') { currentIndex++; }

var key = WebUtility.UrlDecode(parts[0]);
var value = WebUtility.UrlDecode(parts[1]);
if (currentIndex >= baggagestring.Length) { break; }

if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
int keyEnd = currentIndex;

if (baggagestring[currentIndex] != '=')
{
continue;
// Skip Spaces
while (currentIndex < baggagestring.Length && (baggagestring[currentIndex] == Space || baggagestring[currentIndex] == Tab)) { currentIndex++; }

if (currentIndex >= baggagestring.Length) { break; } // Wrong key format
}

if (baggageList is null)
if (baggagestring[currentIndex] != '=') { break; } // wrong key format.

currentIndex++;

// Skip spaces
while (currentIndex < baggagestring.Length && (baggagestring[currentIndex] == Space || baggagestring[currentIndex] == Tab)) { currentIndex++; }

if (currentIndex >= baggagestring.Length) { break; } // Wrong value format

int valueStart = currentIndex;

// Search end of the value
while (currentIndex < baggagestring.Length && baggagestring[currentIndex] != Space && baggagestring[currentIndex] != Tab &&
baggagestring[currentIndex] != Comma && baggagestring[currentIndex] != Semicolon)
{ currentIndex++; }

if (keyStart < keyEnd && valueStart < currentIndex)
{
baggageList = new();
int keyValueLength = (keyEnd - keyStart) + (currentIndex - valueStart);
if (keyValueLength > MaxKeyValueLength || keyValueLength + baggageLength >= MaxBaggageLength)
{
break;
}

if (baggageList is null)
{
baggageList = new();
}

baggageLength += keyValueLength;

// Insert in reverse order for asp.net compatability.
baggageList.Insert(0, new KeyValuePair<string, string?>(
WebUtility.UrlDecode(baggagestring.Substring(keyStart, keyEnd - keyStart)).Trim(s_trimmingSpaceCharacters),
WebUtility.UrlDecode(baggagestring.Substring(valueStart, currentIndex - valueStart)).Trim(s_trimmingSpaceCharacters)));

if (baggageList.Count >= MaxBaggageItems)
{
break;
}
}

baggageList.Add(new KeyValuePair<string, string?>(key, value));
}
// Skip to end of values
while (currentIndex < baggagestring.Length && baggagestring[currentIndex] != Comma) { currentIndex++; }

currentIndex++; // Move to next key-value entry
} while (currentIndex < baggagestring.Length);

baggage = baggageList;
return baggageList != null;
Expand Down Expand Up @@ -220,7 +265,6 @@ internal static void CopyStringToSpan(string s, Span<char> span)
span[i] = s[i];
}
}

}

internal class LegacyTextMapPropagator : TextMapPropagator
Expand Down