Skip to content

Commit

Permalink
Fix bug when handling of multiple cookie entries with the same name
Browse files Browse the repository at this point in the history
  • Loading branch information
stevejgordon committed Mar 13, 2024
1 parent 2805f3a commit 0080d0e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/Elastic.Apm/Filters/RequestCookieExtractionFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Elastic.Apm.Filters
/// </summary>
internal class RequestCookieExtractionFilter
{
private static readonly WildcardMatcher[] CookieMatcher = new WildcardMatcher[] { new WildcardMatcher.VerbatimMatcher("Cookie", true) };
private static readonly WildcardMatcher[] CookieMatcher = [new WildcardMatcher.VerbatimMatcher("Cookie", true)];

public static IError Filter(IError error)
{
Expand Down
16 changes: 13 additions & 3 deletions src/Elastic.Apm/Helpers/CookieHeaderParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ public static Dictionary<string, string> ParseCookies(string cookieHeader)
var trimmed = cookieValue.Trim();
var parts = trimmed.Split('=');

if (parts.Length == 2 && !string.IsNullOrEmpty(parts[0]) && !string.IsNullOrEmpty(parts[1]))
// Fow now, we store only the first value for a given key. This aligns to our nodeJS agent behavior.
if (parts.Length == 2
&& !string.IsNullOrEmpty(parts[0])
&& !cookies.ContainsKey(parts[0])
&& !string.IsNullOrEmpty(parts[1]))
{
cookies.Add(parts[0], parts[1]);
}
Expand All @@ -51,7 +55,7 @@ public static Dictionary<string, string> ParseCookies(string cookieHeader)
return cookies;
#else
var span = cookieHeader.AsSpan();

while (span.Length > 0)
{
var foundComma = true;
Expand All @@ -75,8 +79,14 @@ public static Dictionary<string, string> ParseCookies(string cookieHeader)
var keyString = key.ToString();
var valueString = value.ToString();

if (!string.IsNullOrEmpty(keyString) && !string.IsNullOrEmpty(valueString))
// Fow now, we store only the first value for a given key. This aligns to our nodeJS agent behavior.
#if NETSTANDARD2_0
if (!string.IsNullOrEmpty(keyString) && !cookies.ContainsKey(keyString) && !string.IsNullOrEmpty(valueString))
cookies.Add(keyString, valueString);
#else
if (!string.IsNullOrEmpty(keyString) && !string.IsNullOrEmpty(valueString))
cookies.TryAdd(keyString, valueString);
#endif
}

span = span.Slice(foundComma ? separatorIndex + 1 : span.Length);
Expand Down
31 changes: 18 additions & 13 deletions test/Elastic.Apm.Tests/HelpersTests/CookieHeaderParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,36 @@ public void ParsesHeadersCorrectly(string input, Dictionary<string, string> expe
result.Should().Contain(expected);
}

public static IEnumerable<object[]> TestData() => new[] {
new object[] { null, null },
new object[] { "", null },
new object[] { "Key1=Value1", new Dictionary<string, string>() { { "Key1", "Value1" }} },
new object[] { "Key1=Value1,Key2=Value2", new Dictionary<string, string>()
public static IEnumerable<object[]> TestData() => [
[null, null],
["", null],
["Key1=Value1", new Dictionary<string, string>() { { "Key1", "Value1" }}],
[ "Key1=Value1,Key2=Value2", new Dictionary<string, string>()
{
{ "Key1", "Value1" },
{ "Key2", "Value2" }
}},
new object[] { "Key1=Value1,Key2=Value2,Key3=Value3", new Dictionary<string, string>()
}],
[ "Key1=Value1,Key2=Value2,Key3=Value3", new Dictionary<string, string>()
{
{ "Key1", "Value1" },
{ "Key2", "Value2" },
{ "Key3", "Value3" }
}},
new object[] { "Key1=Value1; Key2=Value2", new Dictionary<string, string>()
}],
[ "Key1=Value1; Key2=Value2", new Dictionary<string, string>()
{
{ "Key1", "Value1" },
{ "Key2", "Value2" }
}},
new object[] { "Key1=Value1; Key2=Value2; Key3=Value3", new Dictionary<string, string>()
}],
[ "Key1=Value1; Key2=Value2; Key3=Value3", new Dictionary<string, string>()
{
{ "Key1", "Value1" },
{ "Key2", "Value2" },
{ "Key3", "Value3" }
}}
};
}],
[ "Key1=Value1; Key2=Value2; Key1=Value3", new Dictionary<string, string>()
{
{ "Key1", "Value1" },
{ "Key2", "Value2" }
}],
];
}

0 comments on commit 0080d0e

Please sign in to comment.