Skip to content

Commit

Permalink
Fix binder bug with key=value and array
Browse files Browse the repository at this point in the history
  • Loading branch information
thohng committed Jun 5, 2024
1 parent 8bdc630 commit af9a739
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
20 changes: 15 additions & 5 deletions src/Hosting/ResponseHeadersHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ internal static class ResponseHeadersHelper
nameof(BaseResponseHeadersConfigurationOptions.ContentType),
nameof(BaseResponseHeadersConfigurationOptions.ContentTypeContain),
nameof(BaseResponseHeadersConfigurationOptions.ContentTypeStartWith),
nameof(BaseResponseHeadersConfigurationOptions.Headers),
// nameof(BaseResponseHeadersConfigurationOptions.Headers), binder cause bug between array and key value
"Headers",
nameof(BaseResponseHeadersConfigurationOptions.StatusCode),
nameof(ResponseHeadersConfigurationOptions.IsEnabled),
"IsAnyContentType", // legacy value
Expand Down Expand Up @@ -67,9 +68,14 @@ private static ResponseHandlerEntry ParseHandler(BaseResponseHeadersConfiguratio
{
var headers = new Dictionary<string, string>();

foreach (var item in options.Headers ?? [])
foreach (var item in configuration.GetSection("Headers").GetChildren())
{
if (TryParseKeyValue(item, out var key, out var value)
if (item.Value is { } value1
&& item.Key is { } key1
&& !string.IsNullOrEmpty(key1)
&& !string.IsNullOrEmpty(value1)
&& int.TryParse(key1, out var _)
&& TryParseKeyValue(value1, out var key, out var value)
&& !string.IsNullOrEmpty(key)
&& !string.IsNullOrEmpty(value))
{
Expand Down Expand Up @@ -115,11 +121,15 @@ private static ResponseHandlerEntry ParseHandler(BaseResponseHeadersConfiguratio
headers[key] = value;
}
}
else if (nameof(BaseResponseHeadersConfigurationOptions.Headers).Equals(key, DefaultStringComparison))
else if ("Headers".Equals(key, DefaultStringComparison)) // nameof(BaseResponseHeadersConfigurationOptions.Headers)
{
foreach (var item1 in item.GetChildren())
{
if (item1.Value is { } value1 && item1.Key is { } key1 && !string.IsNullOrEmpty(key1) && !string.IsNullOrEmpty(value1) && !int.TryParse(key1, out var _))
if (item1.Value is { } value1
&& item1.Key is { } key1
&& !string.IsNullOrEmpty(key1)
&& !string.IsNullOrEmpty(value1)
&& !int.TryParse(key1, out var _))
{
headers[key1] = value1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Hosting/ResponseHeadersOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ internal class BaseResponseHeadersConfigurationOptions
public HashSet<string>? ContentType { get; set; }
public HashSet<string>? ContentTypeContain { get; set; }
public HashSet<string>? ContentTypeStartWith { get; set; }
public List<string>? Headers { get; set; }
// public List<string>? Headers { get; set; } binder cause bug between array and key value
}

internal class ResponseHeadersConfigurationOptions : BaseResponseHeadersConfigurationOptions
Expand Down
27 changes: 27 additions & 0 deletions test/Hosting.Test/ResponseHeadersHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -656,4 +656,31 @@ public void HeaderAllTest()
["x-header25"] = "value26",
}, handler.Headers);
}

[Fact]
public void HeaderKeyValueWithEqualTest()
{
var configuration = new ConfigurationManager();
configuration.AddInMemoryCollection(new Dictionary<string, string?>
{
["ResponseHeaders:Headers:x-header28"] = "value29=hex",
});

var options = Parse(configuration, "ResponseHeaders");

Assert.NotNull(options);
Assert.NotNull(options.DefaultHandler);
Assert.Empty(options.Handlers);

var handler = options.DefaultHandler;
Assert.NotNull(handler);
Assert.Empty(handler.ContentTypeMatchEq);
Assert.Empty(handler.ContentTypeMatchContain);
Assert.Empty(handler.ContentTypeMatchStartWith);
Assert.Empty(handler.StatusCode);
Assert.Equal(new Dictionary<string, StringValues>
{
["x-header28"] = "value29=hex",
}, handler.Headers);
}
}

0 comments on commit af9a739

Please sign in to comment.