Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use frozen collections #2272

Merged
merged 1 commit into from
Oct 3, 2023
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
2 changes: 1 addition & 1 deletion docs/docfx/articles/header-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Headers are a very important part of processing HTTP requests and each have thei

## YARP header filtering

YARP automatically removes request and response headers that could impact its ability to forward a request correctly, or that may be used maliciously to bypass features of the proxy. A complete list can be found [here](https://github.com/microsoft/reverse-proxy/blob/main/src/ReverseProxy/Forwarder/RequestUtilities.cs#L70), with some highlights described below.
YARP automatically removes request and response headers that could impact its ability to forward a request correctly, or that may be used maliciously to bypass features of the proxy. A complete list can be found [here](https://github.com/microsoft/reverse-proxy/blob/main/src/ReverseProxy/Forwarder/RequestUtilities.cs#L71), with some highlights described below.

### Connection, KeepAlive, Close

Expand Down
1 change: 1 addition & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
</PropertyGroup>
<!--Package versions-->
<PropertyGroup>
<SystemCollectionsImmutableVersion>8.0.0-rc.1.23419.4</SystemCollectionsImmutableVersion>
<MicrosoftBclTimeProviderVersion>8.0.0-rc.1.23419.4</MicrosoftBclTimeProviderVersion>
<MicrosoftDotNetXUnitExtensionsPackageVersion>8.0.0-beta.23463.1</MicrosoftDotNetXUnitExtensionsPackageVersion>
</PropertyGroup>
Expand Down
11 changes: 6 additions & 5 deletions src/ReverseProxy/Configuration/ConfigValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Linq;
using System.Net;
Expand Down Expand Up @@ -31,11 +32,11 @@ internal sealed class ConfigValidator : IConfigValidator
private readonly IAuthorizationPolicyProvider _authorizationPolicyProvider;
private readonly IYarpRateLimiterPolicyProvider _rateLimiterPolicyProvider;
private readonly ICorsPolicyProvider _corsPolicyProvider;
private readonly IDictionary<string, ILoadBalancingPolicy> _loadBalancingPolicies;
private readonly IDictionary<string, IAffinityFailurePolicy> _affinityFailurePolicies;
private readonly IDictionary<string, IAvailableDestinationsPolicy> _availableDestinationsPolicies;
private readonly IDictionary<string, IActiveHealthCheckPolicy> _activeHealthCheckPolicies;
private readonly IDictionary<string, IPassiveHealthCheckPolicy> _passiveHealthCheckPolicies;
private readonly FrozenDictionary<string, ILoadBalancingPolicy> _loadBalancingPolicies;
private readonly FrozenDictionary<string, IAffinityFailurePolicy> _affinityFailurePolicies;
private readonly FrozenDictionary<string, IAvailableDestinationsPolicy> _availableDestinationsPolicies;
private readonly FrozenDictionary<string, IActiveHealthCheckPolicy> _activeHealthCheckPolicies;
private readonly FrozenDictionary<string, IPassiveHealthCheckPolicy> _passiveHealthCheckPolicies;
private readonly ILogger _logger;


Expand Down
9 changes: 5 additions & 4 deletions src/ReverseProxy/Forwarder/RequestUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Buffers;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -67,7 +68,7 @@ internal static bool ShouldSkipResponseHeader(string headerName)
return _headersToExclude.Contains(headerName);
}

private static readonly HashSet<string> _headersToExclude = new(18, StringComparer.OrdinalIgnoreCase)
private static readonly FrozenSet<string> _headersToExclude = new HashSet<string>(18, StringComparer.OrdinalIgnoreCase)
{
HeaderNames.Connection,
HeaderNames.TransferEncoding,
Expand All @@ -87,11 +88,11 @@ internal static bool ShouldSkipResponseHeader(string headerName)
HeaderNames.TE,
HeaderNames.AltSvc,
HeaderNames.StrictTransportSecurity,
};
}.ToFrozenSet(StringComparer.OrdinalIgnoreCase);

// Headers marked as HttpHeaderType.Content in
// https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Http/src/System/Net/Http/Headers/KnownHeaders.cs
private static readonly HashSet<string> _contentHeaders = new(11, StringComparer.OrdinalIgnoreCase)
private static readonly FrozenSet<string> _contentHeaders = new HashSet<string>(11, StringComparer.OrdinalIgnoreCase)
{
HeaderNames.Allow,
HeaderNames.ContentDisposition,
Expand All @@ -104,7 +105,7 @@ internal static bool ShouldSkipResponseHeader(string headerName)
HeaderNames.ContentType,
HeaderNames.Expires,
HeaderNames.LastModified
};
}.ToFrozenSet(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// Appends the given path and query to the destination prefix while avoiding duplicate '/'.
Expand Down
3 changes: 2 additions & 1 deletion src/ReverseProxy/Health/ActiveHealthCheckMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
Expand All @@ -17,7 +18,7 @@ namespace Yarp.ReverseProxy.Health;
internal partial class ActiveHealthCheckMonitor : IActiveHealthCheckMonitor, IClusterChangeListener, IDisposable
{
private readonly ActiveHealthCheckMonitorOptions _monitorOptions;
private readonly IDictionary<string, IActiveHealthCheckPolicy> _policies;
private readonly FrozenDictionary<string, IActiveHealthCheckPolicy> _policies;
private readonly IProbingRequestFactory _probingRequestFactory;
private readonly ILogger<ActiveHealthCheckMonitor> _logger;

Expand Down
3 changes: 2 additions & 1 deletion src/ReverseProxy/Health/ClusterDestinationsUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
Expand All @@ -13,7 +14,7 @@ namespace Yarp.ReverseProxy.Health;
internal sealed class ClusterDestinationsUpdater : IClusterDestinationsUpdater
{
private readonly ConditionalWeakTable<ClusterState, SemaphoreSlim> _clusterLocks = new ConditionalWeakTable<ClusterState, SemaphoreSlim>();
private readonly IDictionary<string, IAvailableDestinationsPolicy> _destinationPolicies;
private readonly FrozenDictionary<string, IAvailableDestinationsPolicy> _destinationPolicies;

public ClusterDestinationsUpdater(IEnumerable<IAvailableDestinationsPolicy> destinationPolicies)
{
Expand Down
3 changes: 2 additions & 1 deletion src/ReverseProxy/Health/PassiveHealthCheckMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
Expand All @@ -12,7 +13,7 @@ namespace Yarp.ReverseProxy.Health;
public class PassiveHealthCheckMiddleware
{
private readonly RequestDelegate _next;
private readonly IDictionary<string, IPassiveHealthCheckPolicy> _policies;
private readonly FrozenDictionary<string, IPassiveHealthCheckPolicy> _policies;

public PassiveHealthCheckMiddleware(RequestDelegate next, IEnumerable<IPassiveHealthCheckPolicy> policies)
{
Expand Down
3 changes: 2 additions & 1 deletion src/ReverseProxy/LoadBalancing/LoadBalancingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
Expand All @@ -17,7 +18,7 @@ namespace Yarp.ReverseProxy.LoadBalancing;
internal sealed class LoadBalancingMiddleware
{
private readonly ILogger _logger;
private readonly IDictionary<string, ILoadBalancingPolicy> _loadBalancingPolicies;
private readonly FrozenDictionary<string, ILoadBalancingPolicy> _loadBalancingPolicies;
private readonly RequestDelegate _next;

public LoadBalancingMiddleware(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using Yarp.ReverseProxy.Transforms.Builder;
using Yarp.ReverseProxy.Utilities;
Expand All @@ -10,7 +11,7 @@ namespace Yarp.ReverseProxy.SessionAffinity;

internal sealed class AffinitizeTransformProvider : ITransformProvider
{
private readonly IDictionary<string, ISessionAffinityPolicy> _sessionAffinityPolicies;
private readonly FrozenDictionary<string, ISessionAffinityPolicy> _sessionAffinityPolicies;

public AffinitizeTransformProvider(IEnumerable<ISessionAffinityPolicy> sessionAffinityPolicies)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
Expand All @@ -18,8 +19,8 @@ namespace Yarp.ReverseProxy.SessionAffinity;
internal sealed class SessionAffinityMiddleware
{
private readonly RequestDelegate _next;
private readonly IDictionary<string, ISessionAffinityPolicy> _sessionAffinityPolicies;
private readonly IDictionary<string, IAffinityFailurePolicy> _affinityFailurePolicies;
private readonly FrozenDictionary<string, ISessionAffinityPolicy> _sessionAffinityPolicies;
private readonly FrozenDictionary<string, IAffinityFailurePolicy> _affinityFailurePolicies;
private readonly ILogger _logger;

public SessionAffinityMiddleware(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
Expand All @@ -22,12 +23,12 @@ public RequestHeadersAllowedTransform(string[] allowedHeaders)
}

AllowedHeaders = allowedHeaders;
AllowedHeadersSet = new HashSet<string>(allowedHeaders, StringComparer.OrdinalIgnoreCase);
AllowedHeadersSet = new HashSet<string>(allowedHeaders, StringComparer.OrdinalIgnoreCase).ToFrozenSet(StringComparer.OrdinalIgnoreCase);
}

internal string[] AllowedHeaders { get; }

private HashSet<string> AllowedHeadersSet { get; }
private FrozenSet<string> AllowedHeadersSet { get; }

/// <inheritdoc/>
public override ValueTask ApplyAsync(RequestTransformContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http.Headers;
Expand All @@ -24,12 +25,12 @@ public ResponseHeadersAllowedTransform(string[] allowedHeaders)
}

AllowedHeaders = allowedHeaders;
AllowedHeadersSet = new HashSet<string>(allowedHeaders, StringComparer.OrdinalIgnoreCase);
AllowedHeadersSet = new HashSet<string>(allowedHeaders, StringComparer.OrdinalIgnoreCase).ToFrozenSet(StringComparer.OrdinalIgnoreCase);
}

internal string[] AllowedHeaders { get; }

private HashSet<string> AllowedHeadersSet { get; }
private FrozenSet<string> AllowedHeadersSet { get; }

/// <inheritdoc/>
public override ValueTask ApplyAsync(ResponseTransformContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http.Headers;
Expand All @@ -25,12 +26,12 @@ public ResponseTrailersAllowedTransform(string[] allowedHeaders)
}

AllowedHeaders = allowedHeaders;
AllowedHeadersSet = new HashSet<string>(allowedHeaders, StringComparer.OrdinalIgnoreCase);
AllowedHeadersSet = new HashSet<string>(allowedHeaders, StringComparer.OrdinalIgnoreCase).ToFrozenSet(StringComparer.OrdinalIgnoreCase);
}

internal string[] AllowedHeaders { get; }

private HashSet<string> AllowedHeadersSet { get; }
private FrozenSet<string> AllowedHeadersSet { get; }

/// <inheritdoc/>
public override ValueTask ApplyAsync(ResponseTrailersTransformContext context)
Expand Down
7 changes: 4 additions & 3 deletions src/ReverseProxy/Utilities/ServiceLookupHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
// Licensed under the MIT License.

using System;
using System.Collections.Frozen;
using System.Collections.Generic;

namespace Yarp.ReverseProxy.Utilities;

internal static class ServiceLookupHelper
{
public static IDictionary<string, T> ToDictionaryByUniqueId<T>(this IEnumerable<T> services, Func<T, string> idSelector)
public static FrozenDictionary<string, T> ToDictionaryByUniqueId<T>(this IEnumerable<T> services, Func<T, string> idSelector)
{
if (services is null)
{
Expand All @@ -25,10 +26,10 @@ public static IDictionary<string, T> ToDictionaryByUniqueId<T>(this IEnumerable<
}
}

return result;
return result.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase);
}

public static T GetRequiredServiceById<T>(this IDictionary<string, T> services, string? id, string defaultId)
public static T GetRequiredServiceById<T>(this FrozenDictionary<string, T> services, string? id, string defaultId)
{
var lookup = id;
if (string.IsNullOrEmpty(lookup))
Expand Down
1 change: 1 addition & 0 deletions src/ReverseProxy/Yarp.ReverseProxy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<ItemGroup>
<PackageReference Include="System.IO.Hashing" Version="7.0.0" />
<PackageReference Include="System.Collections.Immutable" Version="$(SystemCollectionsImmutableVersion)" Condition="'$(TargetFramework)' != 'net8.0'" />
<PackageReference Include="Microsoft.Bcl.TimeProvider" Version="$(MicrosoftBclTimeProviderVersion)" Condition="'$(TargetFramework)' != 'net8.0'" />
</ItemGroup>

Expand Down
Loading