Skip to content

Commit 4fd6ee7

Browse files
Separate content type exclusion logic from IsJson extension (#651)
* fix isjson and separate exclusion logic * update adapters to use new extension * PR comments
1 parent fb7fb03 commit 4fd6ee7

File tree

4 files changed

+59
-32
lines changed

4 files changed

+59
-32
lines changed

src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
using Azure;
55
using Azure.Data.AppConfiguration;
66
using Azure.Security.KeyVault.Secrets;
7+
using Microsoft.Extensions.Configuration.AzureAppConfiguration.Extensions;
8+
using Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement;
79
using System;
810
using System.Collections.Generic;
911
using System.Linq;
12+
using System.Net.Mime;
1013
using System.Text.Json;
1114
using System.Threading;
1215
using System.Threading.Tasks;
@@ -72,8 +75,15 @@ KeyVaultReferenceException CreateKeyVaultReferenceException(string message, Conf
7275

7376
public bool CanProcess(ConfigurationSetting setting)
7477
{
75-
string contentType = setting?.ContentType?.Split(';')[0].Trim();
76-
return string.Equals(contentType, KeyVaultConstants.ContentType);
78+
if (setting == null ||
79+
string.IsNullOrWhiteSpace(setting.Value) ||
80+
string.IsNullOrWhiteSpace(setting.ContentType))
81+
{
82+
return false;
83+
}
84+
85+
return setting.ContentType.TryParseContentType(out ContentType contentType)
86+
&& contentType.IsKeyVaultReference();
7787
}
7888

7989
public void OnChangeDetected(ConfigurationSetting setting = null)

src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ContentTypeExtensions.cs

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,12 @@ namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.Extensions
1212
{
1313
internal static class ContentTypeExtensions
1414
{
15-
private static readonly IEnumerable<string> ExcludedJsonContentTypes = new[]
16-
{
17-
FeatureManagementConstants.ContentType,
18-
KeyVaultConstants.ContentType
19-
};
20-
2115
public static bool IsAi(this ContentType contentType)
2216
{
2317
return contentType != null &&
2418
contentType.IsJson() &&
19+
!contentType.IsFeatureFlag() &&
20+
!contentType.IsKeyVaultReference() &&
2521
contentType.Parameters.ContainsKey("profile") &&
2622
!string.IsNullOrEmpty(contentType.Parameters["profile"]) &&
2723
contentType.Parameters["profile"].StartsWith(RequestTracingConstants.AIMimeProfile);
@@ -31,6 +27,8 @@ public static bool IsAiChatCompletion(this ContentType contentType)
3127
{
3228
return contentType != null &&
3329
contentType.IsJson() &&
30+
!contentType.IsFeatureFlag() &&
31+
!contentType.IsKeyVaultReference() &&
3432
contentType.Parameters.ContainsKey("profile") &&
3533
!string.IsNullOrEmpty(contentType.Parameters["profile"]) &&
3634
contentType.Parameters["profile"].StartsWith(RequestTracingConstants.AIChatCompletionMimeProfile);
@@ -45,37 +43,43 @@ public static bool IsJson(this ContentType contentType)
4543

4644
string acceptedMainType = "application";
4745
string acceptedSubType = "json";
48-
string mediaType = contentType.MediaType;
49-
50-
if (!ExcludedJsonContentTypes.Contains(mediaType, StringComparer.OrdinalIgnoreCase))
51-
{
52-
ReadOnlySpan<char> mediaTypeSpan = mediaType.AsSpan();
5346

54-
// Since contentType has been validated using System.Net.Mime.ContentType,
55-
// mediaType will always have exactly 2 parts after splitting on '/'
56-
int slashIndex = mediaTypeSpan.IndexOf('/');
47+
ReadOnlySpan<char> mediaTypeSpan = contentType.MediaType.AsSpan();
5748

58-
if (mediaTypeSpan.Slice(0, slashIndex).Equals(acceptedMainType.AsSpan(), StringComparison.OrdinalIgnoreCase))
59-
{
60-
ReadOnlySpan<char> subTypeSpan = mediaTypeSpan.Slice(slashIndex + 1);
49+
// Since contentType has been validated using System.Net.Mime.ContentType,
50+
// mediaType will always have exactly 2 parts after splitting on '/'
51+
int slashIndex = mediaTypeSpan.IndexOf('/');
6152

62-
while (!subTypeSpan.IsEmpty)
63-
{
64-
int plusIndex = subTypeSpan.IndexOf('+');
53+
if (mediaTypeSpan.Slice(0, slashIndex).Equals(acceptedMainType.AsSpan(), StringComparison.OrdinalIgnoreCase))
54+
{
55+
ReadOnlySpan<char> subTypeSpan = mediaTypeSpan.Slice(slashIndex + 1);
6556

66-
ReadOnlySpan<char> currentSubType = plusIndex == -1 ? subTypeSpan : subTypeSpan.Slice(0, plusIndex);
57+
while (!subTypeSpan.IsEmpty)
58+
{
59+
int plusIndex = subTypeSpan.IndexOf('+');
6760

68-
if (currentSubType.Equals(acceptedSubType.AsSpan(), StringComparison.OrdinalIgnoreCase))
69-
{
70-
return true;
71-
}
61+
ReadOnlySpan<char> currentSubType = plusIndex == -1 ? subTypeSpan : subTypeSpan.Slice(0, plusIndex);
7262

73-
subTypeSpan = plusIndex == -1 ? ReadOnlySpan<char>.Empty : subTypeSpan.Slice(plusIndex + 1);
63+
if (currentSubType.Equals(acceptedSubType.AsSpan(), StringComparison.OrdinalIgnoreCase))
64+
{
65+
return true;
7466
}
67+
68+
subTypeSpan = plusIndex == -1 ? ReadOnlySpan<char>.Empty : subTypeSpan.Slice(plusIndex + 1);
7569
}
7670
}
7771

7872
return false;
7973
}
74+
75+
public static bool IsFeatureFlag(this ContentType contentType)
76+
{
77+
return contentType.MediaType.Equals(FeatureManagementConstants.ContentType);
78+
}
79+
80+
public static bool IsKeyVaultReference(this ContentType contentType)
81+
{
82+
return contentType.MediaType.Equals(KeyVaultConstants.ContentType);
83+
}
8084
}
8185
}

src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureManagementKeyValueAdapter.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.Generic;
88
using System.Linq;
9+
using System.Net.Mime;
910
using System.Security.Cryptography;
1011
using System.Text;
1112
using System.Text.Json;
@@ -45,10 +46,20 @@ public Task<IEnumerable<KeyValuePair<string, string>>> ProcessKeyValue(Configura
4546

4647
public bool CanProcess(ConfigurationSetting setting)
4748
{
48-
string contentType = setting?.ContentType?.Split(';')[0].Trim();
49+
if (setting == null ||
50+
string.IsNullOrWhiteSpace(setting.Value) ||
51+
string.IsNullOrWhiteSpace(setting.ContentType))
52+
{
53+
return false;
54+
}
55+
56+
if (setting.Key.StartsWith(FeatureManagementConstants.FeatureFlagMarker))
57+
{
58+
return true;
59+
}
4960

50-
return string.Equals(contentType, FeatureManagementConstants.ContentType) ||
51-
setting.Key.StartsWith(FeatureManagementConstants.FeatureFlagMarker);
61+
return setting.ContentType.TryParseContentType(out ContentType contentType) &&
62+
contentType.IsFeatureFlag();
5263
}
5364

5465
public bool NeedsRefresh()

src/Microsoft.Extensions.Configuration.AzureAppConfiguration/JsonKeyValueAdapter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public bool CanProcess(ConfigurationSetting setting)
5353

5454
if (setting.ContentType.TryParseContentType(out ContentType contentType))
5555
{
56-
return contentType.IsJson();
56+
return contentType.IsJson() &&
57+
!contentType.IsFeatureFlag() &&
58+
!contentType.IsKeyVaultReference();
5759
}
5860

5961
return false;

0 commit comments

Comments
 (0)