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
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
using Azure;
using Azure.Data.AppConfiguration;
using Azure.Security.KeyVault.Secrets;
using Microsoft.Extensions.Configuration.AzureAppConfiguration.Extensions;
using Microsoft.Extensions.Configuration.AzureAppConfiguration.FeatureManagement;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -72,8 +75,15 @@ KeyVaultReferenceException CreateKeyVaultReferenceException(string message, Conf

public bool CanProcess(ConfigurationSetting setting)
{
string contentType = setting?.ContentType?.Split(';')[0].Trim();
return string.Equals(contentType, KeyVaultConstants.ContentType);
if (setting == null ||
string.IsNullOrWhiteSpace(setting.Value) ||
string.IsNullOrWhiteSpace(setting.ContentType))
{
return false;
}

return setting.ContentType.TryParseContentType(out ContentType contentType)
&& contentType.IsKeyVaultReference();
}

public void OnChangeDetected(ConfigurationSetting setting = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.Extensions
{
internal static class ContentTypeExtensions
{
private static readonly IEnumerable<string> ExcludedJsonContentTypes = new[]
{
FeatureManagementConstants.ContentType,
KeyVaultConstants.ContentType
};

public static bool IsAi(this ContentType contentType)
{
return contentType != null &&
contentType.IsJson() &&
!contentType.IsFeatureFlag() &&
!contentType.IsKeyVaultReference() &&
contentType.Parameters.ContainsKey("profile") &&
!string.IsNullOrEmpty(contentType.Parameters["profile"]) &&
contentType.Parameters["profile"].StartsWith(RequestTracingConstants.AIMimeProfile);
Expand All @@ -31,6 +27,8 @@ public static bool IsAiChatCompletion(this ContentType contentType)
{
return contentType != null &&
contentType.IsJson() &&
!contentType.IsFeatureFlag() &&
!contentType.IsKeyVaultReference() &&
contentType.Parameters.ContainsKey("profile") &&
!string.IsNullOrEmpty(contentType.Parameters["profile"]) &&
contentType.Parameters["profile"].StartsWith(RequestTracingConstants.AIChatCompletionMimeProfile);
Expand All @@ -45,37 +43,43 @@ public static bool IsJson(this ContentType contentType)

string acceptedMainType = "application";
string acceptedSubType = "json";
string mediaType = contentType.MediaType;

if (!ExcludedJsonContentTypes.Contains(mediaType, StringComparer.OrdinalIgnoreCase))
{
ReadOnlySpan<char> mediaTypeSpan = mediaType.AsSpan();

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

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

while (!subTypeSpan.IsEmpty)
{
int plusIndex = subTypeSpan.IndexOf('+');
if (mediaTypeSpan.Slice(0, slashIndex).Equals(acceptedMainType.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
ReadOnlySpan<char> subTypeSpan = mediaTypeSpan.Slice(slashIndex + 1);

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

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

subTypeSpan = plusIndex == -1 ? ReadOnlySpan<char>.Empty : subTypeSpan.Slice(plusIndex + 1);
if (currentSubType.Equals(acceptedSubType.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
return true;
}

subTypeSpan = plusIndex == -1 ? ReadOnlySpan<char>.Empty : subTypeSpan.Slice(plusIndex + 1);
}
}

return false;
}

public static bool IsFeatureFlag(this ContentType contentType)
{
return contentType.MediaType.Equals(FeatureManagementConstants.ContentType);
}

public static bool IsKeyVaultReference(this ContentType contentType)
{
return contentType.MediaType.Equals(KeyVaultConstants.ContentType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
Expand Down Expand Up @@ -45,10 +46,20 @@ public Task<IEnumerable<KeyValuePair<string, string>>> ProcessKeyValue(Configura

public bool CanProcess(ConfigurationSetting setting)
{
string contentType = setting?.ContentType?.Split(';')[0].Trim();
if (setting == null ||
string.IsNullOrWhiteSpace(setting.Value) ||
string.IsNullOrWhiteSpace(setting.ContentType))
{
return false;
}

if (setting.Key.StartsWith(FeatureManagementConstants.FeatureFlagMarker))
{
return true;
}

return string.Equals(contentType, FeatureManagementConstants.ContentType) ||
setting.Key.StartsWith(FeatureManagementConstants.FeatureFlagMarker);
return setting.ContentType.TryParseContentType(out ContentType contentType) &&
contentType.IsFeatureFlag();
}

public bool NeedsRefresh()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ public bool CanProcess(ConfigurationSetting setting)

if (setting.ContentType.TryParseContentType(out ContentType contentType))
{
return contentType.IsJson();
return contentType.IsJson() &&
!contentType.IsFeatureFlag() &&
!contentType.IsKeyVaultReference();
}

return false;
Expand Down