Fixup indentations changes (#1391)
* Fixup indendation changes * Revert unintended changes * More indentations
This commit is contained in:
Родитель
0016457609
Коммит
a5b36816f1
|
@ -38,9 +38,9 @@ public class ResourceSerializers : IResourceSerializers
|
|||
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
|
||||
ContractResolver = new ReadOnlyJsonContractResolver(),
|
||||
Converters = new List<JsonConverter>
|
||||
{
|
||||
new Iso8601TimeSpanConverter(),
|
||||
},
|
||||
{
|
||||
new Iso8601TimeSpanConverter(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -36,14 +36,14 @@ public class CustomResourceDefinitionGenerator : ICustomResourceDefinitionGenera
|
|||
{
|
||||
SchemaType = SchemaType.OpenApi3,
|
||||
TypeMappers =
|
||||
{
|
||||
new ObjectTypeMapper(
|
||||
typeof(V1ObjectMeta),
|
||||
new JsonSchema
|
||||
{
|
||||
Type = JsonObjectType.Object,
|
||||
}),
|
||||
},
|
||||
{
|
||||
new ObjectTypeMapper(
|
||||
typeof(V1ObjectMeta),
|
||||
new JsonSchema
|
||||
{
|
||||
Type = JsonObjectType.Object,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
_serializerSettings = new JsonSerializerSettings
|
||||
|
@ -55,9 +55,9 @@ public class CustomResourceDefinitionGenerator : ICustomResourceDefinitionGenera
|
|||
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
|
||||
ContractResolver = new ReadOnlyJsonContractResolver(),
|
||||
Converters = new List<JsonConverter>
|
||||
{
|
||||
new Iso8601TimeSpanConverter(),
|
||||
},
|
||||
{
|
||||
new Iso8601TimeSpanConverter(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -87,11 +87,11 @@ public class CustomResourceDefinitionGenerator : ICustomResourceDefinitionGenera
|
|||
scope: scope,
|
||||
versions: new List<V1CustomResourceDefinitionVersion>
|
||||
{
|
||||
new V1CustomResourceDefinitionVersion(
|
||||
name: names.ApiVersion,
|
||||
served: true,
|
||||
storage: true,
|
||||
schema: new V1CustomResourceValidation(schema)),
|
||||
new V1CustomResourceDefinitionVersion(
|
||||
name: names.ApiVersion,
|
||||
served: true,
|
||||
storage: true,
|
||||
schema: new V1CustomResourceValidation(schema)),
|
||||
})));
|
||||
}
|
||||
|
||||
|
|
|
@ -40,39 +40,39 @@ public class TestClusterHostBuilder
|
|||
CurrentContext = "test-context",
|
||||
Contexts = new[]
|
||||
{
|
||||
new Context
|
||||
new Context
|
||||
{
|
||||
Name = "test-context",
|
||||
ContextDetails = new ContextDetails
|
||||
{
|
||||
Name = "test-context",
|
||||
ContextDetails = new ContextDetails
|
||||
{
|
||||
Namespace = "test-namespace",
|
||||
Cluster = "test-cluster",
|
||||
User = "test-user",
|
||||
}
|
||||
Namespace = "test-namespace",
|
||||
Cluster = "test-cluster",
|
||||
User = "test-user",
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
Clusters = new[]
|
||||
{
|
||||
new Cluster
|
||||
new Cluster
|
||||
{
|
||||
Name = "test-cluster",
|
||||
ClusterEndpoint = new ClusterEndpoint
|
||||
{
|
||||
Name = "test-cluster",
|
||||
ClusterEndpoint = new ClusterEndpoint
|
||||
{
|
||||
Server = ServerUrl,
|
||||
}
|
||||
Server = ServerUrl,
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
Users = new[]
|
||||
{
|
||||
new User
|
||||
new User
|
||||
{
|
||||
Name = "test-user",
|
||||
UserCredentials = new UserCredentials
|
||||
{
|
||||
Name = "test-user",
|
||||
UserCredentials = new UserCredentials
|
||||
{
|
||||
Token = "test-token",
|
||||
}
|
||||
Token = "test-token",
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var clientConfiguration = KubernetesClientConfiguration.BuildConfigFromConfigObject(kubeConfig);
|
||||
|
|
|
@ -37,8 +37,8 @@ public class TestClusterStartup
|
|||
|
||||
app.Use(next => async context =>
|
||||
{
|
||||
// This is a no-op, but very convenient for setting a breakpoint to see per-request details.
|
||||
await next(context);
|
||||
// This is a no-op, but very convenient for setting a breakpoint to see per-request details.
|
||||
await next(context);
|
||||
});
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints => endpoints.MapControllers());
|
||||
|
|
|
@ -14,11 +14,11 @@ public class RateLimitingQueueTests
|
|||
public void AddRateLimitedCallsWhenAndAddDelay()
|
||||
{
|
||||
var whenResults = new Dictionary<string, TimeSpan>
|
||||
{
|
||||
{ "one", TimeSpan.FromMilliseconds(15) },
|
||||
{ "two", TimeSpan.FromMilliseconds(0) },
|
||||
{ "three", TimeSpan.FromMilliseconds(30) },
|
||||
};
|
||||
{
|
||||
{ "one", TimeSpan.FromMilliseconds(15) },
|
||||
{ "two", TimeSpan.FromMilliseconds(0) },
|
||||
{ "three", TimeSpan.FromMilliseconds(30) },
|
||||
};
|
||||
var whenCalls = new List<string>();
|
||||
var rateLimiter = new FakeRateLimiter<string>
|
||||
{
|
||||
|
@ -41,16 +41,16 @@ public class RateLimitingQueueTests
|
|||
|
||||
Assert.Equal(new[]
|
||||
{
|
||||
"one",
|
||||
"two",
|
||||
"three"
|
||||
}, whenCalls);
|
||||
"one",
|
||||
"two",
|
||||
"three"
|
||||
}, whenCalls);
|
||||
|
||||
Assert.Equal(new[]
|
||||
{
|
||||
("one", TimeSpan.FromMilliseconds(15)),
|
||||
("two", TimeSpan.FromMilliseconds(0)),
|
||||
("three", TimeSpan.FromMilliseconds(30))
|
||||
}, addAfterCalls);
|
||||
("one", TimeSpan.FromMilliseconds(15)),
|
||||
("two", TimeSpan.FromMilliseconds(0)),
|
||||
("three", TimeSpan.FromMilliseconds(30))
|
||||
}, addAfterCalls);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,9 +185,9 @@ public class LimiterTests
|
|||
|
||||
var waits = new List<Task>
|
||||
{
|
||||
limiter.WaitAsync(cancellation.Token),
|
||||
limiter.WaitAsync(cancellation.Token),
|
||||
limiter.WaitAsync(cancellation.Token),
|
||||
limiter.WaitAsync(cancellation.Token),
|
||||
limiter.WaitAsync(cancellation.Token),
|
||||
limiter.WaitAsync(cancellation.Token),
|
||||
};
|
||||
|
||||
var taskOne = await Task.WhenAny(waits).ConfigureAwait(false);
|
||||
|
|
|
@ -78,11 +78,11 @@ public class OperatorHandlerTests
|
|||
namespaceProperty: "test-namespace",
|
||||
ownerReferences: new[]
|
||||
{
|
||||
new V1OwnerReference(
|
||||
uid: typical.Uid(),
|
||||
apiVersion: typical.ApiVersion,
|
||||
kind: typical.Kind,
|
||||
name: typical.Name())
|
||||
new V1OwnerReference(
|
||||
uid: typical.Uid(),
|
||||
apiVersion: typical.ApiVersion,
|
||||
kind: typical.Kind,
|
||||
name: typical.Name())
|
||||
}));
|
||||
|
||||
typicalInformer.Callback(WatchEventType.Added, typical);
|
||||
|
|
|
@ -24,9 +24,9 @@ public class ResourceSerializersTests
|
|||
name: "the-name"),
|
||||
rules: new[]
|
||||
{
|
||||
new V1PolicyRule(
|
||||
resourceNames: new []{"*"},
|
||||
verbs: new []{"*"}),
|
||||
new V1PolicyRule(
|
||||
resourceNames: new []{"*"},
|
||||
verbs: new []{"*"}),
|
||||
});
|
||||
|
||||
var json = Serializers.SerializeJson(resource);
|
||||
|
@ -43,19 +43,19 @@ public class ResourceSerializersTests
|
|||
public void DictionarySerializesToJson()
|
||||
{
|
||||
var dictionary = new Dictionary<string, object> {
|
||||
{ "apiVersion", $"{V1Role.KubeGroup}/{V1Role.KubeApiVersion}" },
|
||||
{ "kind", V1Role.KubeKind },
|
||||
{ "metadata", new Dictionary<string, object>{
|
||||
{ "name", "the-name" } ,
|
||||
{ "namespace", "the-namespace" } ,
|
||||
}},
|
||||
{ "rules", new List<object>{
|
||||
new Dictionary<string, object>{
|
||||
{ "resourceNames", new List<object> { "*" } },
|
||||
{ "verbs", new List<object> { "*" } },
|
||||
},
|
||||
}},
|
||||
};
|
||||
{ "apiVersion", $"{V1Role.KubeGroup}/{V1Role.KubeApiVersion}" },
|
||||
{ "kind", V1Role.KubeKind },
|
||||
{ "metadata", new Dictionary<string, object>{
|
||||
{ "name", "the-name" } ,
|
||||
{ "namespace", "the-namespace" } ,
|
||||
}},
|
||||
{ "rules", new List<object>{
|
||||
new Dictionary<string, object>{
|
||||
{ "resourceNames", new List<object> { "*" } },
|
||||
{ "verbs", new List<object> { "*" } },
|
||||
},
|
||||
}},
|
||||
};
|
||||
|
||||
var json = Serializers.SerializeJson(dictionary);
|
||||
|
||||
|
@ -127,19 +127,19 @@ rules:
|
|||
public void ConvertDictionaryToResource()
|
||||
{
|
||||
var dictionary = new Dictionary<string, object> {
|
||||
{ "apiVersion", $"{V1Role.KubeGroup}/{V1Role.KubeApiVersion}" },
|
||||
{ "kind", V1Role.KubeKind },
|
||||
{ "metadata", new Dictionary<string, object>{
|
||||
{ "name", "the-name" } ,
|
||||
{ "namespace", "the-namespace" } ,
|
||||
}},
|
||||
{ "rules", new List<object>{
|
||||
new Dictionary<string, object>{
|
||||
{ "resourceNames", new List<object> { "*" } },
|
||||
{ "verbs", new List<object> { "*" } },
|
||||
},
|
||||
}},
|
||||
};
|
||||
{ "apiVersion", $"{V1Role.KubeGroup}/{V1Role.KubeApiVersion}" },
|
||||
{ "kind", V1Role.KubeKind },
|
||||
{ "metadata", new Dictionary<string, object>{
|
||||
{ "name", "the-name" } ,
|
||||
{ "namespace", "the-namespace" } ,
|
||||
}},
|
||||
{ "rules", new List<object>{
|
||||
new Dictionary<string, object>{
|
||||
{ "resourceNames", new List<object> { "*" } },
|
||||
{ "verbs", new List<object> { "*" } },
|
||||
},
|
||||
}},
|
||||
};
|
||||
|
||||
var role = Serializers.Convert<V1Role>(dictionary);
|
||||
|
||||
|
|
|
@ -345,8 +345,8 @@ internal sealed class ConfigurationConfigProvider : IProxyConfigProvider, IDispo
|
|||
DangerousAcceptAnyServerCertificate = section.ReadBool(nameof(HttpClientConfig.DangerousAcceptAnyServerCertificate)),
|
||||
MaxConnectionsPerServer = section.ReadInt32(nameof(HttpClientConfig.MaxConnectionsPerServer)),
|
||||
#if NET
|
||||
EnableMultipleHttp2Connections = section.ReadBool(nameof(HttpClientConfig.EnableMultipleHttp2Connections)),
|
||||
RequestHeaderEncoding = section[nameof(HttpClientConfig.RequestHeaderEncoding)],
|
||||
EnableMultipleHttp2Connections = section.ReadBool(nameof(HttpClientConfig.EnableMultipleHttp2Connections)),
|
||||
RequestHeaderEncoding = section[nameof(HttpClientConfig.RequestHeaderEncoding)],
|
||||
#endif
|
||||
WebProxy = webProxy
|
||||
};
|
||||
|
@ -364,7 +364,7 @@ internal sealed class ConfigurationConfigProvider : IProxyConfigProvider, IDispo
|
|||
ActivityTimeout = section.ReadTimeSpan(nameof(ForwarderRequestConfig.ActivityTimeout)),
|
||||
Version = section.ReadVersion(nameof(ForwarderRequestConfig.Version)),
|
||||
#if NET
|
||||
VersionPolicy = section.ReadEnum<HttpVersionPolicy>(nameof(ForwarderRequestConfig.VersionPolicy)),
|
||||
VersionPolicy = section.ReadEnum<HttpVersionPolicy>(nameof(ForwarderRequestConfig.VersionPolicy)),
|
||||
#endif
|
||||
AllowResponseBuffering = section.ReadBool(nameof(ForwarderRequestConfig.AllowResponseBuffering))
|
||||
};
|
||||
|
|
|
@ -62,11 +62,11 @@ public sealed record HttpClientConfig
|
|||
&& DangerousAcceptAnyServerCertificate == other.DangerousAcceptAnyServerCertificate
|
||||
&& MaxConnectionsPerServer == other.MaxConnectionsPerServer
|
||||
#if NET
|
||||
&& EnableMultipleHttp2Connections == other.EnableMultipleHttp2Connections
|
||||
&& EnableMultipleHttp2Connections == other.EnableMultipleHttp2Connections
|
||||
// Comparing by reference is fine here since Encoding.GetEncoding returns the same instance for each encoding.
|
||||
&& RequestHeaderEncoding == other.RequestHeaderEncoding
|
||||
#endif
|
||||
&& WebProxy == other.WebProxy;
|
||||
&& WebProxy == other.WebProxy;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
@ -75,9 +75,9 @@ public sealed record HttpClientConfig
|
|||
DangerousAcceptAnyServerCertificate,
|
||||
MaxConnectionsPerServer,
|
||||
#if NET
|
||||
EnableMultipleHttp2Connections,
|
||||
EnableMultipleHttp2Connections,
|
||||
RequestHeaderEncoding,
|
||||
#endif
|
||||
WebProxy);
|
||||
WebProxy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,9 +54,9 @@ public sealed record ForwarderRequestConfig
|
|||
|
||||
return ActivityTimeout == other.ActivityTimeout
|
||||
#if NET
|
||||
&& VersionPolicy == other.VersionPolicy
|
||||
&& VersionPolicy == other.VersionPolicy
|
||||
#endif
|
||||
&& Version == other.Version
|
||||
&& Version == other.Version
|
||||
&& AllowResponseBuffering == other.AllowResponseBuffering;
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,9 @@ public sealed record ForwarderRequestConfig
|
|||
{
|
||||
return HashCode.Combine(ActivityTimeout,
|
||||
#if NET
|
||||
VersionPolicy,
|
||||
VersionPolicy,
|
||||
#endif
|
||||
Version,
|
||||
Version,
|
||||
AllowResponseBuffering);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -788,7 +788,7 @@ internal sealed class HttpForwarder : IHttpForwarder
|
|||
#if NET
|
||||
var versionPolicy = ProtocolHelper.GetVersionPolicy(msg.VersionPolicy);
|
||||
#else
|
||||
var versionPolicy = "RequestVersionOrLower";
|
||||
var versionPolicy = "RequestVersionOrLower";
|
||||
#endif
|
||||
_proxying(logger, msg.RequestUri!.AbsoluteUri, version, versionPolicy, streaming, null);
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public static class RequestUtilities
|
|||
#if NET
|
||||
HeaderNames.AltSvc,
|
||||
#else
|
||||
"Alt-Svc",
|
||||
"Alt-Svc",
|
||||
#endif
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
|
@ -233,11 +233,11 @@ public static class RequestUtilities
|
|||
// bool[] would use 3 cache lines (Array info + 128 bytes)
|
||||
// So we use 128 bits rather than 128 bytes/bools
|
||||
private static readonly uint[] ValidPathChars = {
|
||||
0b_0000_0000__0000_0000__0000_0000__0000_0000, // 0x00 - 0x1F
|
||||
0b_0010_1111__1111_1111__1111_1111__1101_0010, // 0x20 - 0x3F
|
||||
0b_1000_0111__1111_1111__1111_1111__1111_1111, // 0x40 - 0x5F
|
||||
0b_0100_0111__1111_1111__1111_1111__1111_1110, // 0x60 - 0x7F
|
||||
};
|
||||
0b_0000_0000__0000_0000__0000_0000__0000_0000, // 0x00 - 0x1F
|
||||
0b_0010_1111__1111_1111__1111_1111__1101_0010, // 0x20 - 0x3F
|
||||
0b_1000_0111__1111_1111__1111_1111__1111_1111, // 0x40 - 0x5F
|
||||
0b_0100_0111__1111_1111__1111_1111__1111_1110, // 0x60 - 0x7F
|
||||
};
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static bool IsValidPathChar(char c)
|
||||
|
@ -247,8 +247,8 @@ public static class RequestUtilities
|
|||
var i = (int)c;
|
||||
|
||||
// Array is in chunks of 32 bits, so get offset by dividing by 32
|
||||
var offset = i >> 5; // i / 32;
|
||||
// Significant bit position is the remainder of the above calc; i % 32 => i & 31
|
||||
var offset = i >> 5; // i / 32;
|
||||
// Significant bit position is the remainder of the above calc; i % 32 => i & 31
|
||||
var significantBit = 1u << (i & 31);
|
||||
|
||||
// Check offset in bounds and check if significant bit set
|
||||
|
|
|
@ -126,7 +126,7 @@ internal sealed class StreamCopyHttpContent : HttpContent
|
|||
#else
|
||||
private
|
||||
#endif
|
||||
async Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken)
|
||||
async Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken)
|
||||
{
|
||||
if (Interlocked.Exchange(ref _started, 1) == 1)
|
||||
{
|
||||
|
|
|
@ -24,8 +24,8 @@ internal class HealthyAndUnknownDestinationsPolicy : IAvailableDestinationsPolic
|
|||
{
|
||||
availableDestinations = allDestinations.Where(destination =>
|
||||
{
|
||||
// Only consider the current state if those checks are enabled.
|
||||
var healthState = destination.Health;
|
||||
// Only consider the current state if those checks are enabled.
|
||||
var healthState = destination.Health;
|
||||
var active = activeEnabled ? healthState.Active : DestinationHealth.Unknown;
|
||||
var passive = passiveEnabled ? healthState.Passive : DestinationHealth.Unknown;
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ internal static class IReverseProxyBuilderExtensions
|
|||
|
||||
builder.Services.TryAddSingleton<IClusterDestinationsUpdater, ClusterDestinationsUpdater>();
|
||||
builder.Services.TryAddEnumerable(new[] {
|
||||
ServiceDescriptor.Singleton<IAvailableDestinationsPolicy, HealthyAndUnknownDestinationsPolicy>(),
|
||||
ServiceDescriptor.Singleton<IAvailableDestinationsPolicy, HealthyOrPanicDestinationsPolicy>()
|
||||
});
|
||||
ServiceDescriptor.Singleton<IAvailableDestinationsPolicy, HealthyAndUnknownDestinationsPolicy>(),
|
||||
ServiceDescriptor.Singleton<IAvailableDestinationsPolicy, HealthyOrPanicDestinationsPolicy>()
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -66,12 +66,12 @@ internal static class IReverseProxyBuilderExtensions
|
|||
builder.Services.TryAddSingleton<IRandomFactory, RandomFactory>();
|
||||
|
||||
builder.Services.TryAddEnumerable(new[] {
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, FirstLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, LeastRequestsLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, RandomLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, PowerOfTwoChoicesLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, RoundRobinLoadBalancingPolicy>()
|
||||
});
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, FirstLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, LeastRequestsLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, RandomLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, PowerOfTwoChoicesLoadBalancingPolicy>(),
|
||||
ServiceDescriptor.Singleton<ILoadBalancingPolicy, RoundRobinLoadBalancingPolicy>()
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
@ -79,13 +79,13 @@ internal static class IReverseProxyBuilderExtensions
|
|||
public static IReverseProxyBuilder AddSessionAffinityPolicies(this IReverseProxyBuilder builder)
|
||||
{
|
||||
builder.Services.TryAddEnumerable(new[] {
|
||||
ServiceDescriptor.Singleton<IAffinityFailurePolicy, RedistributeAffinityFailurePolicy>(),
|
||||
ServiceDescriptor.Singleton<IAffinityFailurePolicy, Return503ErrorAffinityFailurePolicy>()
|
||||
});
|
||||
ServiceDescriptor.Singleton<IAffinityFailurePolicy, RedistributeAffinityFailurePolicy>(),
|
||||
ServiceDescriptor.Singleton<IAffinityFailurePolicy, Return503ErrorAffinityFailurePolicy>()
|
||||
});
|
||||
builder.Services.TryAddEnumerable(new[] {
|
||||
ServiceDescriptor.Singleton<ISessionAffinityPolicy, CookieSessionAffinityPolicy>(),
|
||||
ServiceDescriptor.Singleton<ISessionAffinityPolicy, CustomHeaderSessionAffinityPolicy>()
|
||||
});
|
||||
ServiceDescriptor.Singleton<ISessionAffinityPolicy, CookieSessionAffinityPolicy>(),
|
||||
ServiceDescriptor.Singleton<ISessionAffinityPolicy, CustomHeaderSessionAffinityPolicy>()
|
||||
});
|
||||
builder.AddTransforms<AffinitizeTransformProvider>();
|
||||
|
||||
return builder;
|
||||
|
|
|
@ -597,9 +597,9 @@ internal sealed class ProxyConfigManager : EndpointDataSource, IDisposable
|
|||
private static class Log
|
||||
{
|
||||
private static readonly Action<ILogger, string, Exception?> _clusterAdded = LoggerMessage.Define<string>(
|
||||
LogLevel.Debug,
|
||||
EventIds.ClusterAdded,
|
||||
"Cluster '{clusterId}' has been added.");
|
||||
LogLevel.Debug,
|
||||
EventIds.ClusterAdded,
|
||||
"Cluster '{clusterId}' has been added.");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception?> _clusterChanged = LoggerMessage.Define<string>(
|
||||
LogLevel.Debug,
|
||||
|
@ -707,4 +707,3 @@ internal sealed class ProxyConfigManager : EndpointDataSource, IDisposable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,8 +71,8 @@ public static class ReverseProxyServiceCollectionExtensions
|
|||
|
||||
builder.Services.AddSingleton<IProxyConfigProvider>(sp =>
|
||||
{
|
||||
// This is required because we're capturing the configuration via a closure
|
||||
return new ConfigurationConfigProvider(sp.GetRequiredService<ILogger<ConfigurationConfigProvider>>(), config);
|
||||
// This is required because we're capturing the configuration via a closure
|
||||
return new ConfigurationConfigProvider(sp.GetRequiredService<ILogger<ConfigurationConfigProvider>>(), config);
|
||||
});
|
||||
|
||||
return builder;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
|
|
@ -234,9 +234,9 @@ internal sealed class ResponseTransformFactory : ITransformFactory
|
|||
TransformHelpers.CheckTooManyParameters(transformValues, expected: 1);
|
||||
var headersList = allowedTrailers.Split(';', options: StringSplitOptions.RemoveEmptyEntries
|
||||
#if NET
|
||||
| StringSplitOptions.TrimEntries
|
||||
| StringSplitOptions.TrimEntries
|
||||
#endif
|
||||
);
|
||||
);
|
||||
context.AddResponseTrailersAllowed(headersList);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -312,9 +312,9 @@ public static class TlsFrameHelper
|
|||
SslProtocols.Tls11 => s_protocolMismatch11,
|
||||
SslProtocols.Tls => s_protocolMismatch10,
|
||||
#pragma warning disable 0618
|
||||
SslProtocols.Ssl3 => s_protocolMismatch30,
|
||||
SslProtocols.Ssl3 => s_protocolMismatch30,
|
||||
#pragma warning restore 0618
|
||||
_ => Array.Empty<byte>(),
|
||||
_ => Array.Empty<byte>(),
|
||||
};
|
||||
|
||||
public static byte[] CreateAlertFrame(SslProtocols version, TlsAlertDescription reason)
|
||||
|
|
|
@ -21,8 +21,8 @@ public static class WebSocketsTelemetryExtensions
|
|||
{
|
||||
return app.Use(next =>
|
||||
{
|
||||
// Avoid exposing another extension method (AddWebSocketsTelemetry) just because of IClock
|
||||
var clock = app.ApplicationServices.GetServices<IClock>().FirstOrDefault() ?? new Clock();
|
||||
// Avoid exposing another extension method (AddWebSocketsTelemetry) just because of IClock
|
||||
var clock = app.ApplicationServices.GetServices<IClock>().FirstOrDefault() ?? new Clock();
|
||||
return new WebSocketsTelemetryMiddleware(next, clock).InvokeAsync;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -223,11 +223,11 @@ internal sealed class Discoverer : IDiscoverer
|
|||
Address = endpointUri.AbsoluteUri,
|
||||
Health = healthEndpointUri?.AbsoluteUri,
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "PartitionId", partition.Id.ToString() ?? string.Empty },
|
||||
{ "NamedPartitionName", partition.Name ?? string.Empty },
|
||||
{ "ReplicaId", replica.Id.ToString() ?? string.Empty }
|
||||
}
|
||||
{
|
||||
{ "PartitionId", partition.Id.ToString() ?? string.Empty },
|
||||
{ "NamedPartitionName", partition.Name ?? string.Empty },
|
||||
{ "ReplicaId", replica.Id.ToString() ?? string.Empty }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ internal static class LabelsParser
|
|||
#if NET
|
||||
headerMatches[headerIndex].Values = kvp.Value.Split(',', StringSplitOptions.TrimEntries);
|
||||
#elif NETCOREAPP3_1
|
||||
headerMatches[headerIndex].Values = kvp.Value.Split(',').Select(val => val.Trim()).ToList();
|
||||
headerMatches[headerIndex].Values = kvp.Value.Split(',').Select(val => val.Trim()).ToList();
|
||||
#else
|
||||
#error A target framework was added to the project and needs to be added to this condition.
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,7 @@ public
|
|||
#else
|
||||
internal
|
||||
#endif
|
||||
sealed class KestrelMetrics
|
||||
sealed class KestrelMetrics
|
||||
{
|
||||
public KestrelMetrics() => Timestamp = DateTime.UtcNow;
|
||||
|
||||
|
|
|
@ -115,15 +115,15 @@ public class TestEnvironment
|
|||
ClusterId = clusterId,
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "destination1", new DestinationConfig() { Address = destinationAddress } }
|
||||
{ "destination1", new DestinationConfig() { Address = destinationAddress } }
|
||||
},
|
||||
HttpClient = new HttpClientConfig
|
||||
{
|
||||
DangerousAcceptAnyServerCertificate = useHttpsOnDestination,
|
||||
#if NET
|
||||
RequestHeaderEncoding = requestHeaderEncoding?.WebName,
|
||||
RequestHeaderEncoding = requestHeaderEncoding?.WebName,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
(cluster, route) = configTransformer(cluster, route);
|
||||
var proxyBuilder = services.AddReverseProxy().LoadFromMemory(new[] { route }, new[] { cluster });
|
||||
|
@ -148,7 +148,7 @@ public class TestEnvironment
|
|||
{
|
||||
config.AddInMemoryCollection(new Dictionary<string, string>()
|
||||
{
|
||||
{ "Logging:LogLevel:Microsoft.AspNetCore.Hosting.Diagnostics", "Information" }
|
||||
{ "Logging:LogLevel:Microsoft.AspNetCore.Hosting.Diagnostics", "Information" }
|
||||
});
|
||||
})
|
||||
.ConfigureLogging((hostingContext, loggingBuilder) =>
|
||||
|
@ -163,12 +163,12 @@ public class TestEnvironment
|
|||
.UseKestrel(kestrel =>
|
||||
{
|
||||
#if NET
|
||||
if (requestHeaderEncoding != null)
|
||||
if (requestHeaderEncoding != null)
|
||||
{
|
||||
kestrel.RequestHeaderEncodingSelector = _ => requestHeaderEncoding;
|
||||
}
|
||||
#endif
|
||||
kestrel.Listen(IPAddress.Loopback, 0, listenOptions =>
|
||||
kestrel.Listen(IPAddress.Loopback, 0, listenOptions =>
|
||||
{
|
||||
listenOptions.Protocols = protocols;
|
||||
if (useHttps)
|
||||
|
|
|
@ -88,13 +88,13 @@ public class DistributedTracingTests
|
|||
var downstreamTraceId = downstreamContext.TraceId.ToHexString();
|
||||
var downstreamSpanId = downstreamContext.SpanId.ToHexString();
|
||||
#else
|
||||
// 3.1 does not have ActivityContext
|
||||
Assert.Equal(client.TraceStateString, proxy[TraceState]);
|
||||
Assert.Equal(client.TraceStateString, downstream[TraceState]);
|
||||
var proxyTraceId = proxy[TraceParent].ToString().Split('-')[1];
|
||||
var proxySpanId = proxy[TraceParent].ToString().Split('-')[2];
|
||||
var downstreamTraceId = downstream[TraceParent].ToString().Split('-')[1];
|
||||
var downstreamSpanId = downstream[TraceParent].ToString().Split('-')[2];
|
||||
// 3.1 does not have ActivityContext
|
||||
Assert.Equal(client.TraceStateString, proxy[TraceState]);
|
||||
Assert.Equal(client.TraceStateString, downstream[TraceState]);
|
||||
var proxyTraceId = proxy[TraceParent].ToString().Split('-')[1];
|
||||
var proxySpanId = proxy[TraceParent].ToString().Split('-')[2];
|
||||
var downstreamTraceId = downstream[TraceParent].ToString().Split('-')[1];
|
||||
var downstreamSpanId = downstream[TraceParent].ToString().Split('-')[2];
|
||||
#endif
|
||||
|
||||
Assert.Equal(client.TraceId.ToHexString(), proxyTraceId);
|
||||
|
@ -103,8 +103,8 @@ public class DistributedTracingTests
|
|||
#if NET6_0_OR_GREATER
|
||||
Assert.NotEqual(proxySpanId, downstreamSpanId);
|
||||
#else
|
||||
// Before 6.0, YARP is just pass-through as far as distributed tracing is concerned
|
||||
Assert.Equal(proxySpanId, downstreamSpanId);
|
||||
// Before 6.0, YARP is just pass-through as far as distributed tracing is concerned
|
||||
Assert.Equal(proxySpanId, downstreamSpanId);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -118,8 +118,8 @@ public class DistributedTracingTests
|
|||
#if NET6_0_OR_GREATER
|
||||
Assert.NotEqual(proxyId, downstreamId);
|
||||
#else
|
||||
// Before 6.0, YARP is just pass-through as far as distributed tracing is concerned
|
||||
Assert.Equal(proxyId, downstreamId);
|
||||
// Before 6.0, YARP is just pass-through as far as distributed tracing is concerned
|
||||
Assert.Equal(proxyId, downstreamId);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@ public class Expect100ContinueTests
|
|||
|
||||
if (destResponseCode == 200)
|
||||
{
|
||||
// 100 response code is sent automatically on reading Body.
|
||||
await ReadContent(context, bodyTcs, Encoding.UTF8.GetByteCount(contentString));
|
||||
// 100 response code is sent automatically on reading Body.
|
||||
await ReadContent(context, bodyTcs, Encoding.UTF8.GetByteCount(contentString));
|
||||
}
|
||||
|
||||
context.Response.StatusCode = destResponseCode;
|
||||
|
@ -181,63 +181,63 @@ public class Expect100ContinueTests
|
|||
|
||||
// Fix was implemented in https://github.com/dotnet/runtime/pull/58548
|
||||
#if NET7_0_OR_GREATER
|
||||
[Theory]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http1, false)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http2, false)]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http2, false)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http1, false)]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http1, true)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http2, true)]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http2, true)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http1, true)]
|
||||
public async Task PostExpect100_SkipRequestBodyWithUnsuccesfulResponseCode(HttpProtocols proxyProtocol, HttpProtocols destProtocol, bool useContentLength)
|
||||
{
|
||||
var requestBodyTcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
[Theory]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http1, false)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http2, false)]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http2, false)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http1, false)]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http1, true)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http2, true)]
|
||||
[InlineData(HttpProtocols.Http1, HttpProtocols.Http2, true)]
|
||||
[InlineData(HttpProtocols.Http2, HttpProtocols.Http1, true)]
|
||||
public async Task PostExpect100_SkipRequestBodyWithUnsuccesfulResponseCode(HttpProtocols proxyProtocol, HttpProtocols destProtocol, bool useContentLength)
|
||||
{
|
||||
var requestBodyTcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var contentString = new string('a', 1024 * 1024 * 10);
|
||||
var test = new TestEnvironment(
|
||||
async context =>
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
|
||||
var responseBody = Encoding.UTF8.GetBytes(contentString + "Response");
|
||||
if (useContentLength)
|
||||
{
|
||||
context.Response.Headers.ContentLength = responseBody.Length;
|
||||
}
|
||||
|
||||
await context.Response.Body.WriteAsync(responseBody.AsMemory());
|
||||
},
|
||||
proxyBuilder => {
|
||||
proxyBuilder.Services.AddSingleton<IForwarderHttpClientFactory, TestForwarderHttpClientFactory>();
|
||||
},
|
||||
proxyApp => { },
|
||||
proxyProtocol: proxyProtocol,
|
||||
useHttpsOnDestination: true,
|
||||
useHttpsOnProxy: true,
|
||||
configTransformer: (c, r) =>
|
||||
{
|
||||
c = c with
|
||||
{
|
||||
HttpRequest = new ForwarderRequestConfig
|
||||
{
|
||||
Version = destProtocol == HttpProtocols.Http2 ? HttpVersion.Version20 : HttpVersion.Version11,
|
||||
}
|
||||
};
|
||||
return (c, r);
|
||||
});
|
||||
|
||||
await test.Invoke(async uri =>
|
||||
var contentString = new string('a', 1024 * 1024 * 10);
|
||||
var test = new TestEnvironment(
|
||||
async context =>
|
||||
{
|
||||
await ProcessHttpRequest(new Uri(uri), proxyProtocol, contentString, useContentLength, 400, cancelResponse:false, contentRead: false, async response =>
|
||||
{
|
||||
Assert.Equal(400, (int)response.StatusCode);
|
||||
context.Response.StatusCode = 400;
|
||||
|
||||
var actualResponse = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(contentString + "Response", actualResponse);
|
||||
});
|
||||
var responseBody = Encoding.UTF8.GetBytes(contentString + "Response");
|
||||
if (useContentLength)
|
||||
{
|
||||
context.Response.Headers.ContentLength = responseBody.Length;
|
||||
}
|
||||
|
||||
await context.Response.Body.WriteAsync(responseBody.AsMemory());
|
||||
},
|
||||
proxyBuilder => {
|
||||
proxyBuilder.Services.AddSingleton<IForwarderHttpClientFactory, TestForwarderHttpClientFactory>();
|
||||
},
|
||||
proxyApp => { },
|
||||
proxyProtocol: proxyProtocol,
|
||||
useHttpsOnDestination: true,
|
||||
useHttpsOnProxy: true,
|
||||
configTransformer: (c, r) =>
|
||||
{
|
||||
c = c with
|
||||
{
|
||||
HttpRequest = new ForwarderRequestConfig
|
||||
{
|
||||
Version = destProtocol == HttpProtocols.Http2 ? HttpVersion.Version20 : HttpVersion.Version11,
|
||||
}
|
||||
};
|
||||
return (c, r);
|
||||
});
|
||||
}
|
||||
|
||||
await test.Invoke(async uri =>
|
||||
{
|
||||
await ProcessHttpRequest(new Uri(uri), proxyProtocol, contentString, useContentLength, 400, cancelResponse:false, contentRead: false, async response =>
|
||||
{
|
||||
Assert.Equal(400, (int)response.StatusCode);
|
||||
|
||||
var actualResponse = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal(contentString + "Response", actualResponse);
|
||||
});
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
private static async Task ReadContent(Microsoft.AspNetCore.Http.HttpContext context, TaskCompletionSource<string> bodyTcs, int byteCount)
|
||||
|
|
|
@ -194,12 +194,12 @@ public class HeaderTests
|
|||
|
||||
var lines = response.Split("\r\n");
|
||||
Assert.Equal("HTTP/1.1 200 OK", lines[0]);
|
||||
// Order varies across vesions.
|
||||
// Assert.Equal("Content-Length: 0", lines[1]);
|
||||
// Assert.Equal("Connection: close", lines[2]);
|
||||
// Assert.StartsWith("Date: ", lines[3]);
|
||||
// Assert.Equal("Server: Kestrel", lines[4]);
|
||||
Assert.Equal("Referer: ", lines[5]);
|
||||
// Order varies across vesions.
|
||||
// Assert.Equal("Content-Length: 0", lines[1]);
|
||||
// Assert.Equal("Connection: close", lines[2]);
|
||||
// Assert.StartsWith("Date: ", lines[3]);
|
||||
// Assert.Equal("Server: Kestrel", lines[4]);
|
||||
Assert.Equal("Referer: ", lines[5]);
|
||||
Assert.Equal("custom: ", lines[6]);
|
||||
Assert.Equal("", lines[7]);
|
||||
});
|
||||
|
@ -317,8 +317,8 @@ public class HeaderTests
|
|||
|
||||
requestBuilder.Append(encoding.GetString(buffer, 0, count));
|
||||
|
||||
// End of the request
|
||||
if (requestBuilder.Length >= 4 &&
|
||||
// End of the request
|
||||
if (requestBuilder.Length >= 4 &&
|
||||
requestBuilder[^4] == '\r' && requestBuilder[^3] == '\n' &&
|
||||
requestBuilder[^2] == '\r' && requestBuilder[^1] == '\n')
|
||||
{
|
||||
|
|
|
@ -36,7 +36,7 @@ public class HttpForwarderCancellationTests
|
|||
var resetFeature = context.Features.Get<IHttpResetFeature>();
|
||||
Assert.NotNull(resetFeature);
|
||||
resetFeature.Reset(0); // NO_ERROR
|
||||
},
|
||||
},
|
||||
proxyBuilder => { },
|
||||
proxyApp =>
|
||||
{
|
||||
|
|
|
@ -101,32 +101,32 @@ public class TelemetryConsumptionTests
|
|||
|
||||
var expected = new[]
|
||||
{
|
||||
"OnRequestStart-Kestrel",
|
||||
"OnForwarderInvoke",
|
||||
"OnForwarderStart",
|
||||
"OnForwarderStage-SendAsyncStart",
|
||||
"OnRequestStart-Kestrel",
|
||||
"OnForwarderInvoke",
|
||||
"OnForwarderStart",
|
||||
"OnForwarderStage-SendAsyncStart",
|
||||
#if NET
|
||||
"OnRequestStart",
|
||||
"OnConnectStart",
|
||||
"OnConnectStop",
|
||||
"OnHandshakeStart",
|
||||
"OnHandshakeStop",
|
||||
"OnConnectionEstablished",
|
||||
"OnRequestStart",
|
||||
"OnConnectStart",
|
||||
"OnConnectStop",
|
||||
"OnHandshakeStart",
|
||||
"OnHandshakeStop",
|
||||
"OnConnectionEstablished",
|
||||
#if NET6_0_OR_GREATER
|
||||
"OnRequestLeftQueue",
|
||||
"OnRequestLeftQueue",
|
||||
#endif
|
||||
"OnRequestHeadersStart",
|
||||
"OnRequestHeadersStop",
|
||||
"OnResponseHeadersStart",
|
||||
"OnResponseHeadersStop",
|
||||
"OnRequestStop",
|
||||
"OnRequestHeadersStart",
|
||||
"OnRequestHeadersStop",
|
||||
"OnResponseHeadersStart",
|
||||
"OnResponseHeadersStop",
|
||||
"OnRequestStop",
|
||||
#endif
|
||||
"OnForwarderStage-SendAsyncStop",
|
||||
"OnForwarderStage-ResponseContentTransferStart",
|
||||
"OnContentTransferred",
|
||||
"OnForwarderStop",
|
||||
"OnRequestStop-Kestrel"
|
||||
};
|
||||
"OnForwarderStage-SendAsyncStop",
|
||||
"OnForwarderStage-ResponseContentTransferStart",
|
||||
"OnContentTransferred",
|
||||
"OnForwarderStop",
|
||||
"OnRequestStop-Kestrel"
|
||||
};
|
||||
|
||||
foreach (var consumerType in new[] { typeof(TelemetryConsumer), typeof(SecondTelemetryConsumer) })
|
||||
{
|
||||
|
@ -158,19 +158,19 @@ public class TelemetryConsumptionTests
|
|||
|
||||
var expected = new[]
|
||||
{
|
||||
"OnRequestStart",
|
||||
"OnConnectStart",
|
||||
"OnConnectStop",
|
||||
"OnConnectionEstablished",
|
||||
"OnRequestStart",
|
||||
"OnConnectStart",
|
||||
"OnConnectStop",
|
||||
"OnConnectionEstablished",
|
||||
#if NET6_0_OR_GREATER
|
||||
"OnRequestLeftQueue",
|
||||
"OnRequestLeftQueue",
|
||||
#endif
|
||||
"OnRequestHeadersStart",
|
||||
"OnRequestHeadersStop",
|
||||
"OnResponseHeadersStart",
|
||||
"OnResponseHeadersStop",
|
||||
"OnRequestStop"
|
||||
};
|
||||
"OnRequestHeadersStart",
|
||||
"OnRequestHeadersStop",
|
||||
"OnResponseHeadersStart",
|
||||
"OnResponseHeadersStop",
|
||||
"OnRequestStop"
|
||||
};
|
||||
|
||||
foreach (var consumerType in new[] { typeof(TelemetryConsumer), typeof(SecondTelemetryConsumer) })
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ public class TelemetryConsumptionTests
|
|||
IForwarderTelemetryConsumer,
|
||||
IKestrelTelemetryConsumer
|
||||
#if NET
|
||||
,
|
||||
,
|
||||
IHttpTelemetryConsumer,
|
||||
INameResolutionTelemetryConsumer,
|
||||
INetSecurityTelemetryConsumer,
|
||||
|
@ -247,8 +247,8 @@ public class TelemetryConsumptionTests
|
|||
public void OnRequestStart(DateTime timestamp, string connectionId, string requestId, string httpVersion, string path, string method) => AddStage($"{nameof(OnRequestStart)}-Kestrel", timestamp);
|
||||
public void OnRequestStop(DateTime timestamp, string connectionId, string requestId, string httpVersion, string path, string method) => AddStage($"{nameof(OnRequestStop)}-Kestrel", timestamp);
|
||||
#else
|
||||
public void OnRequestStart(DateTime timestamp, string connectionId, string requestId) => AddStage($"{nameof(OnRequestStart)}-Kestrel", timestamp);
|
||||
public void OnRequestStop(DateTime timestamp, string connectionId, string requestId) => AddStage($"{nameof(OnRequestStop)}-Kestrel", timestamp);
|
||||
public void OnRequestStart(DateTime timestamp, string connectionId, string requestId) => AddStage($"{nameof(OnRequestStart)}-Kestrel", timestamp);
|
||||
public void OnRequestStop(DateTime timestamp, string connectionId, string requestId) => AddStage($"{nameof(OnRequestStop)}-Kestrel", timestamp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -270,14 +270,14 @@ public class TelemetryConsumptionTests
|
|||
|
||||
services.AddSingleton<IMetricsConsumer<ForwarderMetrics>>(consumer);
|
||||
#if NET
|
||||
services.AddSingleton<IMetricsConsumer<KestrelMetrics>>(consumer);
|
||||
services.AddSingleton<IMetricsConsumer<KestrelMetrics>>(consumer);
|
||||
services.AddSingleton<IMetricsConsumer<HttpMetrics>>(consumer);
|
||||
services.AddSingleton<IMetricsConsumer<SocketsMetrics>>(consumer);
|
||||
services.AddSingleton<IMetricsConsumer<NetSecurityMetrics>>(consumer);
|
||||
services.AddSingleton<IMetricsConsumer<NameResolutionMetrics>>(consumer);
|
||||
#endif
|
||||
|
||||
services.AddTelemetryListeners();
|
||||
services.AddTelemetryListeners();
|
||||
},
|
||||
proxyApp => { },
|
||||
useHttpsOnDestination: true);
|
||||
|
@ -289,22 +289,22 @@ public class TelemetryConsumptionTests
|
|||
|
||||
try
|
||||
{
|
||||
// Do some arbitrary DNS work to get metrics, since we're connecting to localhost
|
||||
_ = await Dns.GetHostAddressesAsync("microsoft.com");
|
||||
// Do some arbitrary DNS work to get metrics, since we're connecting to localhost
|
||||
_ = await Dns.GetHostAddressesAsync("microsoft.com");
|
||||
}
|
||||
catch { }
|
||||
|
||||
await Task.WhenAll(
|
||||
WaitAsync(() => consumer.ProxyMetrics.LastOrDefault()?.RequestsStarted > 0, nameof(ForwarderMetrics))
|
||||
#if NET
|
||||
,
|
||||
,
|
||||
WaitAsync(() => consumer.KestrelMetrics.LastOrDefault()?.TotalConnections > 0, nameof(KestrelMetrics)),
|
||||
WaitAsync(() => consumer.HttpMetrics.LastOrDefault()?.RequestsStarted > 0, nameof(HttpMetrics)),
|
||||
WaitAsync(() => consumer.SocketsMetrics.LastOrDefault()?.OutgoingConnectionsEstablished > 0, nameof(SocketsMetrics)),
|
||||
WaitAsync(() => consumer.NetSecurityMetrics.LastOrDefault()?.TotalTlsHandshakes > 0, nameof(NetSecurityMetrics)),
|
||||
WaitAsync(() => consumer.NameResolutionMetrics.LastOrDefault()?.DnsLookupsRequested > 0, nameof(NameResolutionMetrics))
|
||||
#endif
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
VerifyTimestamp(consumer.ProxyMetrics.Last().Timestamp);
|
||||
|
@ -339,7 +339,7 @@ public class TelemetryConsumptionTests
|
|||
private sealed class MetricsConsumer :
|
||||
IMetricsConsumer<ForwarderMetrics>
|
||||
#if NET
|
||||
,
|
||||
,
|
||||
IMetricsConsumer<KestrelMetrics>,
|
||||
IMetricsConsumer<HttpMetrics>,
|
||||
IMetricsConsumer<NameResolutionMetrics>,
|
||||
|
|
|
@ -78,8 +78,8 @@ public class WebSocketTests
|
|||
var targetUri = new Uri(new Uri(uri, UriKind.Absolute), "rawupgrade");
|
||||
using var request = new HttpRequestMessage(HttpMethod.Get, targetUri);
|
||||
|
||||
// TODO: https://github.com/microsoft/reverse-proxy/issues/255 Until this is fixed the "Upgrade: WebSocket" header is required.
|
||||
request.Headers.TryAddWithoutValidation("Upgrade", "WebSocket");
|
||||
// TODO: https://github.com/microsoft/reverse-proxy/issues/255 Until this is fixed the "Upgrade: WebSocket" header is required.
|
||||
request.Headers.TryAddWithoutValidation("Upgrade", "WebSocket");
|
||||
|
||||
request.Headers.TryAddWithoutValidation("Connection", "upgrade");
|
||||
request.Version = new Version(1, 1);
|
||||
|
@ -89,14 +89,14 @@ public class WebSocketTests
|
|||
Assert.Equal(HttpStatusCode.SwitchingProtocols, response.StatusCode);
|
||||
|
||||
#if NET
|
||||
using var rawStream = await response.Content.ReadAsStreamAsync(cts.Token);
|
||||
using var rawStream = await response.Content.ReadAsStreamAsync(cts.Token);
|
||||
#elif NETCOREAPP3_1
|
||||
using var rawStream = await response.Content.ReadAsStreamAsync();
|
||||
using var rawStream = await response.Content.ReadAsStreamAsync();
|
||||
#else
|
||||
#error A target framework was added to the project and needs to be added to this condition.
|
||||
#endif
|
||||
|
||||
var buffer = new byte[1];
|
||||
var buffer = new byte[1];
|
||||
for (var i = 0; i <= 255; i++)
|
||||
{
|
||||
buffer[0] = (byte)i;
|
||||
|
@ -138,13 +138,13 @@ public class WebSocketTests
|
|||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
#if NET
|
||||
Assert.Equal("Hello World", await response.Content.ReadAsStringAsync(cts.Token));
|
||||
Assert.Equal("Hello World", await response.Content.ReadAsStringAsync(cts.Token));
|
||||
#elif NETCOREAPP3_1
|
||||
Assert.Equal("Hello World", await response.Content.ReadAsStringAsync());
|
||||
Assert.Equal("Hello World", await response.Content.ReadAsStringAsync());
|
||||
#else
|
||||
#error A target framework was added to the project and needs to be added to this condition.
|
||||
#endif
|
||||
}, cts.Token);
|
||||
}, cts.Token);
|
||||
}
|
||||
|
||||
private static TestEnvironment CreateTestEnvironment(bool forceUpgradable = false)
|
||||
|
@ -169,8 +169,8 @@ public class WebSocketTests
|
|||
proxyBuilder => { },
|
||||
proxyApp =>
|
||||
{
|
||||
// Mimic the IIS issue https://github.com/microsoft/reverse-proxy/issues/255
|
||||
proxyApp.Use((context, next) =>
|
||||
// Mimic the IIS issue https://github.com/microsoft/reverse-proxy/issues/255
|
||||
proxyApp.Use((context, next) =>
|
||||
{
|
||||
if (forceUpgradable && !(context.Features.Get<IHttpUpgradeFeature>()?.IsUpgradableRequest == true))
|
||||
{
|
||||
|
|
|
@ -116,8 +116,8 @@ public class WebSocketsTelemetryTests
|
|||
{
|
||||
using var client = new ClientWebSocket();
|
||||
|
||||
// Keep sending messages from the client in order to observe a server disconnect sooner
|
||||
client.Options.KeepAliveInterval = TimeSpan.FromMilliseconds(10);
|
||||
// Keep sending messages from the client in order to observe a server disconnect sooner
|
||||
client.Options.KeepAliveInterval = TimeSpan.FromMilliseconds(10);
|
||||
|
||||
await client.ConnectAsync(uri, CancellationToken.None);
|
||||
var webSocket = new WebSocketAdapter(client);
|
||||
|
|
|
@ -24,26 +24,26 @@ public class ClusterConfigTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
HealthCheck = new HealthCheckConfig
|
||||
{
|
||||
Passive = new PassiveHealthCheckConfig
|
||||
|
@ -104,26 +104,26 @@ public class ClusterConfigTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
HealthCheck = new HealthCheckConfig
|
||||
{
|
||||
Passive = new PassiveHealthCheckConfig
|
||||
|
@ -195,26 +195,26 @@ public class ClusterConfigTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
HealthCheck = new HealthCheckConfig
|
||||
{
|
||||
Passive = new PassiveHealthCheckConfig
|
||||
|
@ -382,41 +382,41 @@ public class ClusterConfigTests
|
|||
#endif
|
||||
},
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
Metadata = new Dictionary<string, string> { { "cluster1-K1", "cluster1-V1" }, { "cluster1-K2", "cluster1-V2" } }
|
||||
};
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
// Future 6.0 builds will contain the fix to these missing converters
|
||||
//#if !NET6_0_OR_GREATER
|
||||
//#if !NET6_0_OR_GREATER
|
||||
Converters =
|
||||
{
|
||||
// TimeSpans https://github.com/dotnet/runtime/issues/29932
|
||||
new TimeSpanConverter(),
|
||||
// Version https://github.com/dotnet/runtime/pull/41384
|
||||
new VersionConverter()
|
||||
}
|
||||
//#endif
|
||||
{
|
||||
// TimeSpans https://github.com/dotnet/runtime/issues/29932
|
||||
new TimeSpanConverter(),
|
||||
// Version https://github.com/dotnet/runtime/pull/41384
|
||||
new VersionConverter()
|
||||
}
|
||||
//#endif
|
||||
};
|
||||
var json = JsonSerializer.Serialize(cluster1, options);
|
||||
var cluster2 = JsonSerializer.Deserialize<ClusterConfig>(json, options);
|
||||
|
|
|
@ -27,177 +27,177 @@ public class ConfigurationConfigProviderTests
|
|||
private readonly ConfigurationSnapshot _validConfigurationData = new ConfigurationSnapshot()
|
||||
{
|
||||
Clusters =
|
||||
{
|
||||
{
|
||||
new ClusterConfig
|
||||
{
|
||||
new ClusterConfig
|
||||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
HealthCheck = new HealthCheckConfig
|
||||
{
|
||||
Passive = new PassiveHealthCheckConfig
|
||||
{
|
||||
Enabled = true,
|
||||
Policy = "FailureRate",
|
||||
ReactivationPeriod = TimeSpan.FromMinutes(5)
|
||||
},
|
||||
Active = new ActiveHealthCheckConfig
|
||||
{
|
||||
Enabled = true,
|
||||
Interval = TimeSpan.FromSeconds(4),
|
||||
Timeout = TimeSpan.FromSeconds(6),
|
||||
Policy = "Any5xxResponse",
|
||||
Path = "healthCheckPath"
|
||||
},
|
||||
AvailableDestinationsPolicy = "HealthyOrPanic"
|
||||
},
|
||||
LoadBalancingPolicy = LoadBalancingPolicies.Random,
|
||||
SessionAffinity = new SessionAffinityConfig
|
||||
{
|
||||
Enabled = true,
|
||||
FailurePolicy = "Return503Error",
|
||||
Policy = "Cookie",
|
||||
AffinityKeyName = "Key1",
|
||||
Cookie = new SessionAffinityCookieConfig
|
||||
{
|
||||
Domain = "localhost",
|
||||
Expiration = TimeSpan.FromHours(3),
|
||||
HttpOnly = true,
|
||||
IsEssential = true,
|
||||
MaxAge = TimeSpan.FromDays(1),
|
||||
Path = "mypath",
|
||||
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
|
||||
SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None
|
||||
}
|
||||
},
|
||||
HttpClient = new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||
MaxConnectionsPerServer = 10,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
#if NET
|
||||
EnableMultipleHttp2Connections = true,
|
||||
#endif
|
||||
},
|
||||
HttpRequest = new ForwarderRequestConfig()
|
||||
{
|
||||
ActivityTimeout = TimeSpan.FromSeconds(60),
|
||||
Version = Version.Parse("1.0"),
|
||||
#if NET
|
||||
VersionPolicy = HttpVersionPolicy.RequestVersionExact,
|
||||
#endif
|
||||
AllowResponseBuffering = true
|
||||
},
|
||||
Metadata = new Dictionary<string, string> { { "cluster1-K1", "cluster1-V1" }, { "cluster1-K2", "cluster1-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
new ClusterConfig
|
||||
{
|
||||
ClusterId = "cluster2",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "destinationC", new DestinationConfig { Address = "https://localhost:10001/destC" } },
|
||||
{ "destinationD", new DestinationConfig { Address = "https://localhost:10000/destB" } }
|
||||
},
|
||||
LoadBalancingPolicy = LoadBalancingPolicies.RoundRobin
|
||||
}
|
||||
}
|
||||
},
|
||||
Routes =
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
RouteId = "routeA",
|
||||
ClusterId = "cluster1",
|
||||
AuthorizationPolicy = "Default",
|
||||
CorsPolicy = "Default",
|
||||
Order = -1,
|
||||
Match = new RouteMatch
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
Hosts = new List<string> { "host-A" },
|
||||
Methods = new List<string> { "GET", "POST", "DELETE" },
|
||||
Path = "/apis/entities",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader
|
||||
"destinationA",
|
||||
new DestinationConfig
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix
|
||||
Address = "https://localhost:10000/destA",
|
||||
Health = "https://localhost:20000/destA",
|
||||
Metadata = new Dictionary<string, string> { { "destA-K1", "destA-V1" }, { "destA-K2", "destA-V2" } }
|
||||
}
|
||||
},
|
||||
QueryParameters = new[]
|
||||
{
|
||||
new RouteQueryParameter
|
||||
"destinationB",
|
||||
new DestinationConfig
|
||||
{
|
||||
Name = "queryparam1",
|
||||
Values = new[] { "value1" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = QueryParameterMatchMode.Contains
|
||||
Address = "https://localhost:10000/destB",
|
||||
Health = "https://localhost:20000/destB",
|
||||
Metadata = new Dictionary<string, string> { { "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
Transforms = new[]
|
||||
HealthCheck = new HealthCheckConfig
|
||||
{
|
||||
new Dictionary<string, string> { { "RequestHeadersCopy", "true" }, { "PathRemovePrefix", "/apis" } }, new Dictionary<string, string> { { "PathPrefix", "/apis" } }
|
||||
},
|
||||
Metadata = new Dictionary<string, string> { { "routeA-K1", "routeA-V1" }, { "routeA-K2", "routeA-V2" } }
|
||||
},
|
||||
new RouteConfig
|
||||
{
|
||||
RouteId = "routeB",
|
||||
ClusterId = "cluster2",
|
||||
Order = 2,
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new List<string> { "host-B" },
|
||||
Methods = new List<string> { "GET" },
|
||||
Path = "/apis/users",
|
||||
Headers = new[]
|
||||
Passive = new PassiveHealthCheckConfig
|
||||
{
|
||||
new RouteHeader
|
||||
{
|
||||
Name = "header2",
|
||||
Values = new[] { "value2" },
|
||||
IsCaseSensitive = false,
|
||||
Mode = HeaderMatchMode.ExactHeader
|
||||
}
|
||||
Enabled = true,
|
||||
Policy = "FailureRate",
|
||||
ReactivationPeriod = TimeSpan.FromMinutes(5)
|
||||
},
|
||||
QueryParameters = new[]
|
||||
Active = new ActiveHealthCheckConfig
|
||||
{
|
||||
new RouteQueryParameter
|
||||
{
|
||||
Name = "queryparam2",
|
||||
Values = new[] { "value2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = QueryParameterMatchMode.Contains
|
||||
}
|
||||
Enabled = true,
|
||||
Interval = TimeSpan.FromSeconds(4),
|
||||
Timeout = TimeSpan.FromSeconds(6),
|
||||
Policy = "Any5xxResponse",
|
||||
Path = "healthCheckPath"
|
||||
},
|
||||
AvailableDestinationsPolicy = "HealthyOrPanic"
|
||||
},
|
||||
LoadBalancingPolicy = LoadBalancingPolicies.Random,
|
||||
SessionAffinity = new SessionAffinityConfig
|
||||
{
|
||||
Enabled = true,
|
||||
FailurePolicy = "Return503Error",
|
||||
Policy = "Cookie",
|
||||
AffinityKeyName = "Key1",
|
||||
Cookie = new SessionAffinityCookieConfig
|
||||
{
|
||||
Domain = "localhost",
|
||||
Expiration = TimeSpan.FromHours(3),
|
||||
HttpOnly = true,
|
||||
IsEssential = true,
|
||||
MaxAge = TimeSpan.FromDays(1),
|
||||
Path = "mypath",
|
||||
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
|
||||
SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None
|
||||
}
|
||||
},
|
||||
HttpClient = new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||
MaxConnectionsPerServer = 10,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
#if NET
|
||||
EnableMultipleHttp2Connections = true,
|
||||
#endif
|
||||
},
|
||||
HttpRequest = new ForwarderRequestConfig()
|
||||
{
|
||||
ActivityTimeout = TimeSpan.FromSeconds(60),
|
||||
Version = Version.Parse("1.0"),
|
||||
#if NET
|
||||
VersionPolicy = HttpVersionPolicy.RequestVersionExact,
|
||||
#endif
|
||||
AllowResponseBuffering = true
|
||||
},
|
||||
Metadata = new Dictionary<string, string> { { "cluster1-K1", "cluster1-V1" }, { "cluster1-K2", "cluster1-V2" } }
|
||||
}
|
||||
},
|
||||
{
|
||||
new ClusterConfig
|
||||
{
|
||||
ClusterId = "cluster2",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "destinationC", new DestinationConfig { Address = "https://localhost:10001/destC" } },
|
||||
{ "destinationD", new DestinationConfig { Address = "https://localhost:10000/destB" } }
|
||||
},
|
||||
LoadBalancingPolicy = LoadBalancingPolicies.RoundRobin
|
||||
}
|
||||
}
|
||||
},
|
||||
Routes =
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
RouteId = "routeA",
|
||||
ClusterId = "cluster1",
|
||||
AuthorizationPolicy = "Default",
|
||||
CorsPolicy = "Default",
|
||||
Order = -1,
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new List<string> { "host-A" },
|
||||
Methods = new List<string> { "GET", "POST", "DELETE" },
|
||||
Path = "/apis/entities",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix
|
||||
}
|
||||
},
|
||||
QueryParameters = new[]
|
||||
{
|
||||
new RouteQueryParameter
|
||||
{
|
||||
Name = "queryparam1",
|
||||
Values = new[] { "value1" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = QueryParameterMatchMode.Contains
|
||||
}
|
||||
}
|
||||
},
|
||||
Transforms = new[]
|
||||
{
|
||||
new Dictionary<string, string> { { "RequestHeadersCopy", "true" }, { "PathRemovePrefix", "/apis" } }, new Dictionary<string, string> { { "PathPrefix", "/apis" } }
|
||||
},
|
||||
Metadata = new Dictionary<string, string> { { "routeA-K1", "routeA-V1" }, { "routeA-K2", "routeA-V2" } }
|
||||
},
|
||||
new RouteConfig
|
||||
{
|
||||
RouteId = "routeB",
|
||||
ClusterId = "cluster2",
|
||||
Order = 2,
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new List<string> { "host-B" },
|
||||
Methods = new List<string> { "GET" },
|
||||
Path = "/apis/users",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader
|
||||
{
|
||||
Name = "header2",
|
||||
Values = new[] { "value2" },
|
||||
IsCaseSensitive = false,
|
||||
Mode = HeaderMatchMode.ExactHeader
|
||||
}
|
||||
},
|
||||
QueryParameters = new[]
|
||||
{
|
||||
new RouteQueryParameter
|
||||
{
|
||||
Name = "queryparam2",
|
||||
Values = new[] { "value2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = QueryParameterMatchMode.Contains
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private const string _validJsonConfig = @"
|
||||
|
|
|
@ -250,12 +250,12 @@ public class ConfigValidatorTests
|
|||
Path = "/",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
},
|
||||
},
|
||||
ClusterId = "cluster1",
|
||||
};
|
||||
|
@ -279,12 +279,12 @@ public class ConfigValidatorTests
|
|||
Path = "/",
|
||||
QueryParameters = new[]
|
||||
{
|
||||
new RouteQueryParameter()
|
||||
{
|
||||
Name = "queryparam1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
},
|
||||
new RouteQueryParameter()
|
||||
{
|
||||
Name = "queryparam1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
},
|
||||
},
|
||||
ClusterId = "cluster1",
|
||||
};
|
||||
|
@ -308,12 +308,12 @@ public class ConfigValidatorTests
|
|||
Path = "/",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Mode = HeaderMatchMode.Exists
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Mode = HeaderMatchMode.Exists
|
||||
}
|
||||
},
|
||||
},
|
||||
ClusterId = "cluster1",
|
||||
};
|
||||
|
@ -337,12 +337,12 @@ public class ConfigValidatorTests
|
|||
Path = "/",
|
||||
QueryParameters = new[]
|
||||
{
|
||||
new RouteQueryParameter()
|
||||
{
|
||||
Name = "queryparam1",
|
||||
Mode = QueryParameterMatchMode.Exists
|
||||
}
|
||||
},
|
||||
new RouteQueryParameter()
|
||||
{
|
||||
Name = "queryparam1",
|
||||
Mode = QueryParameterMatchMode.Exists
|
||||
}
|
||||
},
|
||||
},
|
||||
ClusterId = "cluster1",
|
||||
};
|
||||
|
|
|
@ -49,9 +49,9 @@ public class DestinationConfigTests
|
|||
Assert.False(options1.Equals(options1 with
|
||||
{
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" }
|
||||
}
|
||||
{
|
||||
{ "destB-K1", "destB-V1" }, { "destB-K2", "destB-V2" }
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -21,22 +21,22 @@ public class RouteConfigTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
Hosts = new[] { "foo:90" },
|
||||
Methods = new[] { "GET", "POST" },
|
||||
Path = "/p",
|
||||
},
|
||||
Metadata = new Dictionary<string, string>()
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
Order = 1,
|
||||
RouteId = "R",
|
||||
};
|
||||
|
@ -49,22 +49,22 @@ public class RouteConfigTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
Hosts = new[] { "foo:90" },
|
||||
Methods = new[] { "GET", "POST" },
|
||||
Path = "/P"
|
||||
},
|
||||
Metadata = new Dictionary<string, string>()
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
Order = 1,
|
||||
RouteId = "r",
|
||||
};
|
||||
|
@ -88,22 +88,22 @@ public class RouteConfigTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
Hosts = new[] { "foo:90" },
|
||||
Methods = new[] { "GET", "POST" },
|
||||
Path = "/p",
|
||||
},
|
||||
Metadata = new Dictionary<string, string>()
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
Order = 1,
|
||||
RouteId = "R",
|
||||
};
|
||||
|
@ -142,30 +142,30 @@ public class RouteConfigTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
Hosts = new[] { "foo:90" },
|
||||
Methods = new[] { "GET", "POST" },
|
||||
Path = "/p",
|
||||
},
|
||||
Metadata = new Dictionary<string, string>()
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
{
|
||||
{ "m", "m1" }
|
||||
},
|
||||
Transforms = new[]
|
||||
{
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "key", "value" },
|
||||
{ "key1", "" }
|
||||
}
|
||||
},
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "key", "value" },
|
||||
{ "key1", "" }
|
||||
}
|
||||
},
|
||||
Order = 1,
|
||||
RouteId = "R",
|
||||
};
|
||||
|
|
|
@ -14,14 +14,14 @@ public class RouteMatchTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
Hosts = new[] { "foo:90" },
|
||||
Methods = new[] { "GET", "POST" },
|
||||
Path = "/p",
|
||||
|
@ -30,14 +30,14 @@ public class RouteMatchTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
Hosts = new[] { "foo:90" },
|
||||
Methods = new[] { "GET", "POST" },
|
||||
Path = "/P",
|
||||
|
@ -57,14 +57,14 @@ public class RouteMatchTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Hi",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
},
|
||||
Hosts = new[] { "foo:90" },
|
||||
Methods = new[] { "GET", "POST" },
|
||||
Path = "/p",
|
||||
|
@ -73,14 +73,14 @@ public class RouteMatchTests
|
|||
{
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Bye",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "Bye",
|
||||
Values = new[] { "v1", "v2" },
|
||||
IsCaseSensitive = true,
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
}
|
||||
}
|
||||
};
|
||||
var c = a with { Hosts = new[] { "bar:90" } };
|
||||
var d = a with { Methods = new[] { "PUT", "POST" } };
|
||||
|
|
|
@ -192,154 +192,154 @@ public class ForwarderHttpClientFactoryTests : TestAutoMockBase
|
|||
{
|
||||
return new[]
|
||||
{
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = false,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = false,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = false,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = false,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = false,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 20,
|
||||
},
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = false,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = null,
|
||||
},
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 20,
|
||||
},
|
||||
},
|
||||
#if NET
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
EnableMultipleHttp2Connections = true
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
EnableMultipleHttp2Connections = false
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
EnableMultipleHttp2Connections = true
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
RequestHeaderEncoding = Encoding.UTF8.WebName,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
EnableMultipleHttp2Connections = false
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
RequestHeaderEncoding = Encoding.UTF8.WebName,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
RequestHeaderEncoding = Encoding.Latin1.WebName,
|
||||
},
|
||||
}
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
RequestHeaderEncoding = Encoding.UTF8.WebName,
|
||||
},
|
||||
},
|
||||
new object[] {
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
RequestHeaderEncoding = Encoding.UTF8.WebName,
|
||||
},
|
||||
new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11,
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
MaxConnectionsPerServer = 10,
|
||||
RequestHeaderEncoding = Encoding.Latin1.WebName,
|
||||
},
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
public static SocketsHttpHandler GetHandler(HttpMessageInvoker client)
|
||||
|
@ -362,11 +362,11 @@ public class ForwarderHttpClientFactoryTests : TestAutoMockBase
|
|||
private (string name, Func<SocketsHttpHandler, object> extractor)[] GetAllExtractors()
|
||||
{
|
||||
return new (string name, Func<SocketsHttpHandler, object> extractor)[] {
|
||||
("SslProtocols", h => h.SslOptions.EnabledSslProtocols),
|
||||
("DangerousAcceptAnyServerCertificate", h => h.SslOptions.RemoteCertificateValidationCallback),
|
||||
("ClientCertificate", h => h.SslOptions.ClientCertificates),
|
||||
("MaxConnectionsPerServer", h => h.MaxConnectionsPerServer),
|
||||
("WebProxy", h => h.Proxy)
|
||||
};
|
||||
("SslProtocols", h => h.SslOptions.EnabledSslProtocols),
|
||||
("DangerousAcceptAnyServerCertificate", h => h.SslOptions.RemoteCertificateValidationCallback),
|
||||
("ClientCertificate", h => h.SslOptions.ClientCertificates),
|
||||
("MaxConnectionsPerServer", h => h.MaxConnectionsPerServer),
|
||||
("WebProxy", h => h.Proxy)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public class ForwarderMiddlewareTests : TestAutoMockBase
|
|||
|
||||
httpContext.Features.Set<IReverseProxyFeature>(
|
||||
new ReverseProxyFeature()
|
||||
{
|
||||
{
|
||||
AvailableDestinations = new List<DestinationState>() { destination1 }.AsReadOnly(),
|
||||
Cluster = clusterModel,
|
||||
Route = routeConfig,
|
||||
|
@ -78,9 +78,9 @@ public class ForwarderMiddlewareTests : TestAutoMockBase
|
|||
requestOptions.ActivityTimeout == httpRequestOptions.ActivityTimeout
|
||||
&& requestOptions.Version == httpRequestOptions.Version
|
||||
#if NET
|
||||
&& requestOptions.VersionPolicy == httpRequestOptions.VersionPolicy
|
||||
&& requestOptions.VersionPolicy == httpRequestOptions.VersionPolicy
|
||||
#endif
|
||||
),
|
||||
),
|
||||
It.IsAny<HttpTransformer>()))
|
||||
.Returns(
|
||||
async () =>
|
||||
|
|
|
@ -83,8 +83,8 @@ public class HttpForwarderTests
|
|||
|
||||
var capturedRequestContent = new MemoryStream();
|
||||
|
||||
// Use CopyToAsync as this is what HttpClient and friends use internally
|
||||
await request.Content.CopyToWithCancellationAsync(capturedRequestContent);
|
||||
// Use CopyToAsync as this is what HttpClient and friends use internally
|
||||
await request.Content.CopyToWithCancellationAsync(capturedRequestContent);
|
||||
capturedRequestContent.Position = 0;
|
||||
var capturedContentText = StreamToString(capturedRequestContent);
|
||||
Assert.Equal("request content", capturedContentText);
|
||||
|
@ -182,8 +182,8 @@ public class HttpForwarderTests
|
|||
|
||||
var capturedRequestContent = new MemoryStream();
|
||||
|
||||
// Use CopyToAsync as this is what HttpClient and friends use internally
|
||||
await request.Content.CopyToWithCancellationAsync(capturedRequestContent);
|
||||
// Use CopyToAsync as this is what HttpClient and friends use internally
|
||||
await request.Content.CopyToWithCancellationAsync(capturedRequestContent);
|
||||
capturedRequestContent.Position = 0;
|
||||
var capturedContentText = StreamToString(capturedRequestContent);
|
||||
Assert.Equal("request content", capturedContentText);
|
||||
|
@ -266,8 +266,8 @@ public class HttpForwarderTests
|
|||
|
||||
var capturedRequestContent = new MemoryStream();
|
||||
|
||||
// Use CopyToAsync as this is what HttpClient and friends use internally
|
||||
await request.Content.CopyToWithCancellationAsync(capturedRequestContent);
|
||||
// Use CopyToAsync as this is what HttpClient and friends use internally
|
||||
await request.Content.CopyToWithCancellationAsync(capturedRequestContent);
|
||||
capturedRequestContent.Position = 0;
|
||||
var capturedContentText = StreamToString(capturedRequestContent);
|
||||
Assert.Equal("request content", capturedContentText);
|
||||
|
@ -596,8 +596,8 @@ public class HttpForwarderTests
|
|||
Assert.Equal(new Version(2, 0), request.Version);
|
||||
Assert.Equal(method, request.Method.Method, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// When adding content-specific headers, we will inject an EmptyHttpContent if no other content is present
|
||||
if (headers.Any())
|
||||
// When adding content-specific headers, we will inject an EmptyHttpContent if no other content is present
|
||||
if (headers.Any())
|
||||
{
|
||||
Assert.NotNull(request.Content);
|
||||
Assert.IsType<EmptyHttpContent>(request.Content);
|
||||
|
@ -609,8 +609,8 @@ public class HttpForwarderTests
|
|||
Assert.Equal(value, Assert.Single(values));
|
||||
}
|
||||
|
||||
// If a custom content is injected, so is a "Content-Length: 0" header
|
||||
Assert.True(request.Content.Headers.TryGetValues(HeaderNames.ContentLength, out var contentLength));
|
||||
// If a custom content is injected, so is a "Content-Length: 0" header
|
||||
Assert.True(request.Content.Headers.TryGetValues(HeaderNames.ContentLength, out var contentLength));
|
||||
Assert.Equal("0", Assert.Single(contentLength));
|
||||
}
|
||||
else
|
||||
|
@ -664,8 +664,8 @@ public class HttpForwarderTests
|
|||
|
||||
Assert.NotNull(request.Content);
|
||||
|
||||
// Must consume the body
|
||||
await request.Content.CopyToWithCancellationAsync(Stream.Null);
|
||||
// Must consume the body
|
||||
await request.Content.CopyToWithCancellationAsync(Stream.Null);
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(Array.Empty<byte>()) };
|
||||
});
|
||||
|
@ -727,8 +727,8 @@ public class HttpForwarderTests
|
|||
|
||||
Assert.NotNull(request.Content);
|
||||
|
||||
// Must consume the body
|
||||
await request.Content.CopyToWithCancellationAsync(Stream.Null);
|
||||
// Must consume the body
|
||||
await request.Content.CopyToWithCancellationAsync(Stream.Null);
|
||||
|
||||
return new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(Array.Empty<byte>()) };
|
||||
});
|
||||
|
@ -753,7 +753,7 @@ public class HttpForwarderTests
|
|||
var events = TestEventListener.Collect();
|
||||
|
||||
// This is an invalid format per spec but may happen due to https://github.com/dotnet/aspnetcore/issues/26461
|
||||
var cookies = new[] { "testA=A_Cookie", "testB=B_Cookie", "testC=C_Cookie" };
|
||||
var cookies = new [] { "testA=A_Cookie", "testB=B_Cookie", "testC=C_Cookie" };
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.Method = "GET";
|
||||
httpContext.Request.Headers.Add(HeaderNames.Cookie, cookies);
|
||||
|
@ -763,8 +763,8 @@ public class HttpForwarderTests
|
|||
var client = MockHttpHandler.CreateClient(
|
||||
(HttpRequestMessage request, CancellationToken cancellationToken) =>
|
||||
{
|
||||
// "testA=A_Cookie; testB=B_Cookie; testC=C_Cookie"
|
||||
var expectedCookieString = string.Join("; ", cookies);
|
||||
// "testA=A_Cookie; testB=B_Cookie; testC=C_Cookie"
|
||||
var expectedCookieString = string.Join("; ", cookies);
|
||||
|
||||
Assert.Equal(new Version(2, 0), request.Version);
|
||||
Assert.Equal("GET", request.Method.Method, StringComparer.OrdinalIgnoreCase);
|
||||
|
@ -808,9 +808,9 @@ public class HttpForwarderTests
|
|||
{
|
||||
Assert.Equal(version, request.Version);
|
||||
#if NET
|
||||
Assert.Equal(versionPolicy, request.VersionPolicy);
|
||||
Assert.Equal(versionPolicy, request.VersionPolicy);
|
||||
#endif
|
||||
Assert.Equal("GET", request.Method.Method, StringComparer.OrdinalIgnoreCase);
|
||||
Assert.Equal("GET", request.Method.Method, StringComparer.OrdinalIgnoreCase);
|
||||
Assert.Null(request.Content);
|
||||
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(Array.Empty<byte>()) };
|
||||
|
@ -858,9 +858,9 @@ public class HttpForwarderTests
|
|||
{
|
||||
Assert.Equal(transformedVersion, request.Version);
|
||||
#if NET
|
||||
Assert.Equal(transformedVersionPolicy, request.VersionPolicy);
|
||||
Assert.Equal(transformedVersionPolicy, request.VersionPolicy);
|
||||
#endif
|
||||
Assert.Equal("GET", request.Method.Method, StringComparer.OrdinalIgnoreCase);
|
||||
Assert.Equal("GET", request.Method.Method, StringComparer.OrdinalIgnoreCase);
|
||||
Assert.Null(request.Content);
|
||||
|
||||
var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(Array.Empty<byte>()) };
|
||||
|
@ -875,10 +875,10 @@ public class HttpForwarderTests
|
|||
Assert.Equal(version, request.Version);
|
||||
request.Version = transformedVersion;
|
||||
#if NET
|
||||
Assert.Equal(versionPolicy, request.VersionPolicy);
|
||||
Assert.Equal(versionPolicy, request.VersionPolicy);
|
||||
request.VersionPolicy = transformedVersionPolicy;
|
||||
#endif
|
||||
return Task.CompletedTask;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1117,8 +1117,8 @@ public class HttpForwarderTests
|
|||
|
||||
Assert.NotNull(request.Content);
|
||||
|
||||
// Must consume the body
|
||||
var body = new MemoryStream();
|
||||
// Must consume the body
|
||||
var body = new MemoryStream();
|
||||
await request.Content.CopyToWithCancellationAsync(body);
|
||||
|
||||
Assert.Equal(expectedReads, body.Length);
|
||||
|
@ -1138,7 +1138,7 @@ public class HttpForwarderTests
|
|||
|
||||
AssertProxyStartStop(events, destinationPrefix, httpContext.Response.StatusCode);
|
||||
events.AssertContainProxyStages(new[] { ForwarderStage.SendAsyncStart, ForwarderStage.SendAsyncStop,
|
||||
ForwarderStage.RequestContentTransferStart, ForwarderStage.ResponseContentTransferStart, });
|
||||
ForwarderStage.RequestContentTransferStart, ForwarderStage.ResponseContentTransferStart, });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1197,8 +1197,8 @@ public class HttpForwarderTests
|
|||
var client = MockHttpHandler.CreateClient(
|
||||
async (HttpRequestMessage request, CancellationToken cancellationToken) =>
|
||||
{
|
||||
// Should throw.
|
||||
await request.Content.CopyToWithCancellationAsync(Stream.Null);
|
||||
// Should throw.
|
||||
await request.Content.CopyToWithCancellationAsync(Stream.Null);
|
||||
return new HttpResponseMessage();
|
||||
});
|
||||
|
||||
|
@ -1213,9 +1213,9 @@ public class HttpForwarderTests
|
|||
|
||||
AssertProxyStartFailedStop(events, destinationPrefix, httpContext.Response.StatusCode, errorFeature.Error);
|
||||
events.AssertContainProxyStages(new[] {
|
||||
ForwarderStage.SendAsyncStart,
|
||||
ForwarderStage.RequestContentTransferStart
|
||||
});
|
||||
ForwarderStage.SendAsyncStart,
|
||||
ForwarderStage.RequestContentTransferStart
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1237,8 +1237,8 @@ public class HttpForwarderTests
|
|||
var client = MockHttpHandler.CreateClient(
|
||||
async (HttpRequestMessage request, CancellationToken cancellationToken) =>
|
||||
{
|
||||
// Doesn't throw for destination errors
|
||||
await request.Content.CopyToWithCancellationAsync(new ThrowStream());
|
||||
// Doesn't throw for destination errors
|
||||
await request.Content.CopyToWithCancellationAsync(new ThrowStream());
|
||||
throw new HttpRequestException();
|
||||
});
|
||||
|
||||
|
@ -1253,9 +1253,9 @@ public class HttpForwarderTests
|
|||
|
||||
AssertProxyStartFailedStop(events, destinationPrefix, httpContext.Response.StatusCode, errorFeature.Error);
|
||||
events.AssertContainProxyStages(new[] {
|
||||
ForwarderStage.SendAsyncStart,
|
||||
ForwarderStage.RequestContentTransferStart
|
||||
});
|
||||
ForwarderStage.SendAsyncStart,
|
||||
ForwarderStage.RequestContentTransferStart
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1278,8 +1278,8 @@ public class HttpForwarderTests
|
|||
var client = MockHttpHandler.CreateClient(
|
||||
async (HttpRequestMessage request, CancellationToken cancellationToken) =>
|
||||
{
|
||||
// should throw
|
||||
try
|
||||
// should throw
|
||||
try
|
||||
{
|
||||
await request.Content.CopyToWithCancellationAsync(new MemoryStream());
|
||||
}
|
||||
|
@ -1604,10 +1604,10 @@ public class HttpForwarderTests
|
|||
var client = MockHttpHandler.CreateClient(
|
||||
(HttpRequestMessage request, CancellationToken cancellationToken) =>
|
||||
{
|
||||
// Background copy
|
||||
_ = request.Content.CopyToWithCancellationAsync(new MemoryStream());
|
||||
// Make sure the request isn't canceled until the response finishes copying.
|
||||
return Task.FromResult(new HttpResponseMessage()
|
||||
// Background copy
|
||||
_ = request.Content.CopyToWithCancellationAsync(new MemoryStream());
|
||||
// Make sure the request isn't canceled until the response finishes copying.
|
||||
return Task.FromResult(new HttpResponseMessage()
|
||||
{
|
||||
Content = new StreamContent(new OnCompletedReadStream(() =>
|
||||
{
|
||||
|
@ -1650,10 +1650,10 @@ public class HttpForwarderTests
|
|||
var client = MockHttpHandler.CreateClient(
|
||||
(HttpRequestMessage request, CancellationToken cancellationToken) =>
|
||||
{
|
||||
// Background copy
|
||||
_ = request.Content.CopyToWithCancellationAsync(new MemoryStream());
|
||||
// Make sure the request isn't canceled until the response finishes copying.
|
||||
return Task.FromResult(new HttpResponseMessage()
|
||||
// Background copy
|
||||
_ = request.Content.CopyToWithCancellationAsync(new MemoryStream());
|
||||
// Make sure the request isn't canceled until the response finishes copying.
|
||||
return Task.FromResult(new HttpResponseMessage()
|
||||
{
|
||||
Content = new StreamContent(new OnCompletedReadStream(() => waitTcs.SetResult(0)))
|
||||
});
|
||||
|
@ -1692,10 +1692,10 @@ public class HttpForwarderTests
|
|||
var client = MockHttpHandler.CreateClient(
|
||||
(HttpRequestMessage request, CancellationToken cancellationToken) =>
|
||||
{
|
||||
// Background copy
|
||||
_ = request.Content.CopyToWithCancellationAsync(new StallStream(waitTcs.Task));
|
||||
// Make sure the request isn't canceled until the response finishes copying.
|
||||
return Task.FromResult(new HttpResponseMessage()
|
||||
// Background copy
|
||||
_ = request.Content.CopyToWithCancellationAsync(new StallStream(waitTcs.Task));
|
||||
// Make sure the request isn't canceled until the response finishes copying.
|
||||
return Task.FromResult(new HttpResponseMessage()
|
||||
{
|
||||
Content = new StreamContent(new OnCompletedReadStream(() => waitTcs.SetResult(0)))
|
||||
});
|
||||
|
@ -2085,31 +2085,31 @@ public class HttpForwarderTests
|
|||
{
|
||||
var headers = new[]
|
||||
{
|
||||
"Connection: close",
|
||||
"Upgrade: test123",
|
||||
"Transfer-Encoding: deflate",
|
||||
"Keep-Alive: timeout=100",
|
||||
"Proxy-Connection: value",
|
||||
"Proxy-Authenticate: value",
|
||||
"Proxy-Authentication-Info: value",
|
||||
"Proxy-Authorization: value",
|
||||
"Proxy-Features: value",
|
||||
"Proxy-Instruction: value",
|
||||
"Security-Scheme: value",
|
||||
"ALPN: value",
|
||||
"Close: value",
|
||||
"TE: value",
|
||||
"HTTP2-Settings: value",
|
||||
"Upgrade-Insecure-Requests: value",
|
||||
"Alt-Svc: value",
|
||||
"Connection: close",
|
||||
"Upgrade: test123",
|
||||
"Transfer-Encoding: deflate",
|
||||
"Keep-Alive: timeout=100",
|
||||
"Proxy-Connection: value",
|
||||
"Proxy-Authenticate: value",
|
||||
"Proxy-Authentication-Info: value",
|
||||
"Proxy-Authorization: value",
|
||||
"Proxy-Features: value",
|
||||
"Proxy-Instruction: value",
|
||||
"Security-Scheme: value",
|
||||
"ALPN: value",
|
||||
"Close: value",
|
||||
"TE: value",
|
||||
"HTTP2-Settings: value",
|
||||
"Upgrade-Insecure-Requests: value",
|
||||
"Alt-Svc: value",
|
||||
#if NET6_0_OR_GREATER
|
||||
"traceparent: value",
|
||||
"Request-Id: value",
|
||||
"tracestate: value",
|
||||
"baggage: value",
|
||||
"Correlation-Context: value",
|
||||
"traceparent: value",
|
||||
"Request-Id: value",
|
||||
"tracestate: value",
|
||||
"baggage: value",
|
||||
"Correlation-Context: value",
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
foreach (var header in headers)
|
||||
{
|
||||
|
@ -2122,11 +2122,11 @@ public class HttpForwarderTests
|
|||
{
|
||||
var headers = new[]
|
||||
{
|
||||
"valid-name-1: \rfoo",
|
||||
"valid-name-2: bar\n",
|
||||
"valid-name-3: foo\r\nbar",
|
||||
"valid-name-4: foo\r\n bar",
|
||||
};
|
||||
"valid-name-1: \rfoo",
|
||||
"valid-name-2: bar\n",
|
||||
"valid-name-3: foo\r\nbar",
|
||||
"valid-name-4: foo\r\n bar",
|
||||
};
|
||||
|
||||
foreach (var header in headers)
|
||||
{
|
||||
|
|
|
@ -15,35 +15,35 @@ public class HttpTransformerTests
|
|||
{
|
||||
private static readonly string[] RestrictedHeaders = new[]
|
||||
{
|
||||
HeaderNames.Connection,
|
||||
HeaderNames.TransferEncoding,
|
||||
HeaderNames.KeepAlive,
|
||||
HeaderNames.Upgrade,
|
||||
"Proxy-Connection",
|
||||
"Proxy-Authenticate",
|
||||
"Proxy-Authentication-Info",
|
||||
"Proxy-Authorization",
|
||||
"Proxy-Features",
|
||||
"Proxy-Instruction",
|
||||
"Security-Scheme",
|
||||
"ALPN",
|
||||
"Close",
|
||||
"HTTP2-Settings",
|
||||
HeaderNames.UpgradeInsecureRequests,
|
||||
HeaderNames.TE,
|
||||
HeaderNames.Connection,
|
||||
HeaderNames.TransferEncoding,
|
||||
HeaderNames.KeepAlive,
|
||||
HeaderNames.Upgrade,
|
||||
"Proxy-Connection",
|
||||
"Proxy-Authenticate",
|
||||
"Proxy-Authentication-Info",
|
||||
"Proxy-Authorization",
|
||||
"Proxy-Features",
|
||||
"Proxy-Instruction",
|
||||
"Security-Scheme",
|
||||
"ALPN",
|
||||
"Close",
|
||||
"HTTP2-Settings",
|
||||
HeaderNames.UpgradeInsecureRequests,
|
||||
HeaderNames.TE,
|
||||
#if NET
|
||||
HeaderNames.AltSvc,
|
||||
HeaderNames.AltSvc,
|
||||
#else
|
||||
"Alt-Svc",
|
||||
"Alt-Svc",
|
||||
#endif
|
||||
#if NET6_0_OR_GREATER
|
||||
HeaderNames.TraceParent,
|
||||
HeaderNames.RequestId,
|
||||
HeaderNames.TraceState,
|
||||
HeaderNames.Baggage,
|
||||
HeaderNames.CorrelationContext,
|
||||
HeaderNames.TraceParent,
|
||||
HeaderNames.RequestId,
|
||||
HeaderNames.TraceState,
|
||||
HeaderNames.Baggage,
|
||||
HeaderNames.CorrelationContext,
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public async Task TransformRequestAsync_RemovesRestrictedHeaders()
|
||||
|
|
|
@ -120,13 +120,13 @@ public class RequestUtilitiesTests
|
|||
{
|
||||
var valids = new char[]
|
||||
{
|
||||
'!', '$', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
':', ';', '=', '@',
|
||||
'A', 'B', 'C', 'D', 'E', 'F','G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'_',
|
||||
'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'~'
|
||||
'!', '$', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
':', ';', '=', '@',
|
||||
'A', 'B', 'C', 'D', 'E', 'F','G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'_',
|
||||
'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'~'
|
||||
};
|
||||
foreach (var c in valids)
|
||||
{
|
||||
|
@ -141,10 +141,10 @@ public class RequestUtilitiesTests
|
|||
{
|
||||
var invalids = new char[]
|
||||
{
|
||||
// Controls
|
||||
(char)0x00, (char)0x01, (char)0x02, (char)0x03, (char)0x04, (char)0x05, (char)0x06, (char)0x00, (char)0x07, (char)0x08, (char)0x09, (char)0x0A, (char)0x0B, (char)0x0C, (char)0x0D, (char)0x0E, (char)0x0F,
|
||||
(char)0x10, (char)0x11, (char)0x02, (char)0x13, (char)0x14, (char)0x15, (char)0x16, (char)0x10, (char)0x17, (char)0x18, (char)0x19, (char)0x1A, (char)0x1B, (char)0x1C, (char)0x1D, (char)0x1E, (char)0x1F,
|
||||
' ', '"', '#', '%', '<', '>', '?', '[', '\\', ']', '^', '`', '{', '|', '}'
|
||||
// Controls
|
||||
(char)0x00, (char)0x01, (char)0x02, (char)0x03, (char)0x04, (char)0x05, (char)0x06, (char)0x00, (char)0x07, (char)0x08, (char)0x09, (char)0x0A, (char)0x0B, (char)0x0C, (char)0x0D, (char)0x0E, (char)0x0F,
|
||||
(char)0x10, (char)0x11, (char)0x02, (char)0x13, (char)0x14, (char)0x15, (char)0x16, (char)0x10, (char)0x17, (char)0x18, (char)0x19, (char)0x1A, (char)0x1B, (char)0x1C, (char)0x1D, (char)0x1E, (char)0x1F,
|
||||
' ', '"', '#', '%', '<', '>', '?', '[', '\\', ']', '^', '`', '{', '|', '}'
|
||||
};
|
||||
foreach (var c in invalids)
|
||||
{
|
||||
|
|
|
@ -24,13 +24,13 @@ public class ConsecutiveFailuresHealthPolicyTests
|
|||
var cluster1 = GetClusterInfo("cluster0", destinationCount: 2, failureThreshold: 3);
|
||||
|
||||
var probingResults0 = new[] {
|
||||
new DestinationProbingResult(cluster0.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.InternalServerError), null),
|
||||
new DestinationProbingResult(cluster0.Destinations.Values.Skip(1).First(), new HttpResponseMessage(HttpStatusCode.OK), null)
|
||||
};
|
||||
new DestinationProbingResult(cluster0.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.InternalServerError), null),
|
||||
new DestinationProbingResult(cluster0.Destinations.Values.Skip(1).First(), new HttpResponseMessage(HttpStatusCode.OK), null)
|
||||
};
|
||||
var probingResults1 = new[] {
|
||||
new DestinationProbingResult(cluster1.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.OK), null),
|
||||
new DestinationProbingResult(cluster1.Destinations.Values.Skip(1).First(), null, new InvalidOperationException())
|
||||
};
|
||||
new DestinationProbingResult(cluster1.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.OK), null),
|
||||
new DestinationProbingResult(cluster1.Destinations.Values.Skip(1).First(), null, new InvalidOperationException())
|
||||
};
|
||||
|
||||
Assert.Equal(HealthCheckConstants.ActivePolicy.ConsecutiveFailures, policy.Name);
|
||||
|
||||
|
@ -71,9 +71,9 @@ public class ConsecutiveFailuresHealthPolicyTests
|
|||
var cluster = GetClusterInfo("cluster0", destinationCount: 2);
|
||||
|
||||
var probingResults = new[] {
|
||||
new DestinationProbingResult(cluster.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.InternalServerError), null),
|
||||
new DestinationProbingResult(cluster.Destinations.Values.Skip(1).First(), new HttpResponseMessage(HttpStatusCode.OK), null)
|
||||
};
|
||||
new DestinationProbingResult(cluster.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.InternalServerError), null),
|
||||
new DestinationProbingResult(cluster.Destinations.Values.Skip(1).First(), new HttpResponseMessage(HttpStatusCode.OK), null)
|
||||
};
|
||||
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
|
@ -99,9 +99,9 @@ public class ConsecutiveFailuresHealthPolicyTests
|
|||
var cluster = GetClusterInfo("cluster0", destinationCount: 2);
|
||||
|
||||
var probingResults = new[] {
|
||||
new DestinationProbingResult(cluster.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.InternalServerError), null),
|
||||
new DestinationProbingResult(cluster.Destinations.Values.Skip(1).First(), new HttpResponseMessage(HttpStatusCode.OK), null)
|
||||
};
|
||||
new DestinationProbingResult(cluster.Destinations.Values.First(), new HttpResponseMessage(HttpStatusCode.InternalServerError), null),
|
||||
new DestinationProbingResult(cluster.Destinations.Values.Skip(1).First(), new HttpResponseMessage(HttpStatusCode.OK), null)
|
||||
};
|
||||
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
|
|
|
@ -51,9 +51,9 @@ public class DefaultProbingRequestFactoryTests
|
|||
},
|
||||
version
|
||||
#if NET
|
||||
, HttpVersionPolicy.RequestVersionExact
|
||||
, HttpVersionPolicy.RequestVersionExact
|
||||
#endif
|
||||
);
|
||||
);
|
||||
var destinationModel = new DestinationModel(new DestinationConfig { Address = "https://localhost:10000/" });
|
||||
var factory = new DefaultProbingRequestFactory();
|
||||
|
||||
|
@ -67,9 +67,9 @@ public class DefaultProbingRequestFactoryTests
|
|||
|
||||
private ClusterModel GetClusterConfig(string id, ActiveHealthCheckConfig healthCheckOptions, Version version
|
||||
#if NET
|
||||
, HttpVersionPolicy versionPolicy = HttpVersionPolicy.RequestVersionExact
|
||||
, HttpVersionPolicy versionPolicy = HttpVersionPolicy.RequestVersionExact
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
return new ClusterModel(
|
||||
new ClusterConfig
|
||||
|
@ -84,9 +84,9 @@ public class DefaultProbingRequestFactoryTests
|
|||
ActivityTimeout = TimeSpan.FromSeconds(60),
|
||||
Version = version,
|
||||
#if NET
|
||||
VersionPolicy = versionPolicy,
|
||||
VersionPolicy = versionPolicy,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
},
|
||||
new HttpMessageInvoker(new HttpClientHandler()));
|
||||
}
|
||||
|
|
|
@ -102,9 +102,9 @@ public class DestinationHealthUpdaterTests
|
|||
var updater = new DestinationHealthUpdater(new Mock<ITimerFactory>().Object, GetClusterUpdater(), new Mock<ILogger<DestinationHealthUpdater>>().Object);
|
||||
|
||||
var newHealthStates = new[] {
|
||||
new NewActiveDestinationHealth(destination0, DestinationHealth.Unhealthy), new NewActiveDestinationHealth(destination1, DestinationHealth.Healthy),
|
||||
new NewActiveDestinationHealth(destination2, DestinationHealth.Unhealthy), new NewActiveDestinationHealth(destination3, DestinationHealth.Healthy)
|
||||
};
|
||||
new NewActiveDestinationHealth(destination0, DestinationHealth.Unhealthy), new NewActiveDestinationHealth(destination1, DestinationHealth.Healthy),
|
||||
new NewActiveDestinationHealth(destination2, DestinationHealth.Unhealthy), new NewActiveDestinationHealth(destination3, DestinationHealth.Healthy)
|
||||
};
|
||||
updater.SetActive(cluster, newHealthStates);
|
||||
|
||||
foreach (var newHealthState in newHealthStates)
|
||||
|
|
|
@ -25,15 +25,15 @@ public class HealtyAndUnknownDesitnationsPolicyTests
|
|||
|
||||
var allDestinations = new[]
|
||||
{
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Healthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d3") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4") { Health = { Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d5") { Health = { Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d6") { Health = { Active = DestinationHealth.Healthy, Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d7") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d8")
|
||||
};
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Healthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d3") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4") { Health = { Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d5") { Health = { Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d6") { Health = { Active = DestinationHealth.Healthy, Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d7") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d8")
|
||||
};
|
||||
var policy = new HealthyAndUnknownDestinationsPolicy();
|
||||
|
||||
var availableDestinations = policy.GetAvailalableDestinations(cluster, allDestinations);
|
||||
|
@ -51,13 +51,13 @@ public class HealtyAndUnknownDesitnationsPolicyTests
|
|||
var cluster = new ClusterConfig() { ClusterId = "cluster1", HealthCheck = config };
|
||||
var allDestinations = new[]
|
||||
{
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Healthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d3") { Health = { Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4"),
|
||||
new DestinationState("d5") { Health = { Active = DestinationHealth.Healthy, Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d6") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Unhealthy } }
|
||||
};
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Healthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d3") { Health = { Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4"),
|
||||
new DestinationState("d5") { Health = { Active = DestinationHealth.Healthy, Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d6") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Unhealthy } }
|
||||
};
|
||||
var policy = new HealthyAndUnknownDestinationsPolicy();
|
||||
|
||||
var availableDestinations = policy.GetAvailalableDestinations(cluster, allDestinations);
|
||||
|
|
|
@ -16,11 +16,11 @@ public class HealthyOrPanicDestinationsPolicyTests
|
|||
|
||||
var allDestinations = new[]
|
||||
{
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Healthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d2") { Health = { Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4")
|
||||
};
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Healthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d2") { Health = { Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4")
|
||||
};
|
||||
var policy = new HealthyOrPanicDestinationsPolicy();
|
||||
|
||||
var availableDestinations = policy.GetAvailalableDestinations(cluster, allDestinations);
|
||||
|
@ -38,11 +38,11 @@ public class HealthyOrPanicDestinationsPolicyTests
|
|||
|
||||
var allDestinations = new[]
|
||||
{
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d2") { Health = { Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Unhealthy } }
|
||||
};
|
||||
new DestinationState("d1") { Health = { Active = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d2") { Health = { Passive = DestinationHealth.Unhealthy } },
|
||||
new DestinationState("d2") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Healthy } },
|
||||
new DestinationState("d4") { Health = { Active = DestinationHealth.Unhealthy, Passive = DestinationHealth.Unhealthy } }
|
||||
};
|
||||
var policy = new HealthyOrPanicDestinationsPolicy();
|
||||
|
||||
var availableDestinations = policy.GetAvailalableDestinations(cluster, allDestinations);
|
||||
|
|
|
@ -42,9 +42,9 @@ public class LoadBalancerMiddlewareTests
|
|||
const string PolicyName = "NonExistentPolicy";
|
||||
var context = CreateContext(PolicyName, new[]
|
||||
{
|
||||
new DestinationState("destination1"),
|
||||
new DestinationState("destination2")
|
||||
});
|
||||
new DestinationState("destination1"),
|
||||
new DestinationState("destination2")
|
||||
});
|
||||
|
||||
var sut = CreateMiddleware(_ => Task.CompletedTask);
|
||||
|
||||
|
@ -57,8 +57,8 @@ public class LoadBalancerMiddlewareTests
|
|||
{
|
||||
var context = CreateContext(LoadBalancingPolicies.FirstAlphabetical, new[]
|
||||
{
|
||||
new DestinationState("destination1")
|
||||
});
|
||||
new DestinationState("destination1")
|
||||
});
|
||||
|
||||
var sut = CreateMiddleware(_ => Task.CompletedTask);
|
||||
|
||||
|
@ -79,9 +79,9 @@ public class LoadBalancerMiddlewareTests
|
|||
// Selects the alphabetically first available destination.
|
||||
var context = CreateContext(LoadBalancingPolicies.FirstAlphabetical, new[]
|
||||
{
|
||||
new DestinationState("destination2"),
|
||||
new DestinationState("destination1"),
|
||||
});
|
||||
new DestinationState("destination2"),
|
||||
new DestinationState("destination1"),
|
||||
});
|
||||
|
||||
var sut = CreateMiddleware(_ => Task.CompletedTask, new FirstLoadBalancingPolicy());
|
||||
|
||||
|
@ -124,9 +124,9 @@ public class LoadBalancerMiddlewareTests
|
|||
|
||||
var context = CreateContext(PolicyName, new[]
|
||||
{
|
||||
new DestinationState("destination1"),
|
||||
new DestinationState("destination2")
|
||||
});
|
||||
new DestinationState("destination1"),
|
||||
new DestinationState("destination2")
|
||||
});
|
||||
|
||||
var policy = new Mock<ILoadBalancingPolicy>();
|
||||
policy
|
||||
|
@ -158,9 +158,9 @@ public class LoadBalancerMiddlewareTests
|
|||
{
|
||||
var destinations = new[]
|
||||
{
|
||||
new DestinationState("destination1"),
|
||||
new DestinationState("destination2")
|
||||
};
|
||||
new DestinationState("destination1"),
|
||||
new DestinationState("destination2")
|
||||
};
|
||||
var context = CreateContext(loadBalancingPolicy: null, destinations);
|
||||
|
||||
var policy = new Mock<ILoadBalancingPolicy>();
|
||||
|
|
|
@ -30,10 +30,10 @@ public class LoadBalancingPoliciesTests : TestAutoMockBase
|
|||
{
|
||||
var destinations = new[]
|
||||
{
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
var loadBalancer = Create<FirstLoadBalancingPolicy>();
|
||||
|
@ -51,10 +51,10 @@ public class LoadBalancingPoliciesTests : TestAutoMockBase
|
|||
{
|
||||
var destinations = new[]
|
||||
{
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
|
||||
const int Iterations = 10;
|
||||
var random = new Random(42);
|
||||
|
@ -76,10 +76,10 @@ public class LoadBalancingPoliciesTests : TestAutoMockBase
|
|||
{
|
||||
var destinations = new[]
|
||||
{
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
destinations[0].ConcurrentRequestCount++;
|
||||
|
||||
const int Iterations = 10;
|
||||
|
@ -105,10 +105,10 @@ public class LoadBalancingPoliciesTests : TestAutoMockBase
|
|||
{
|
||||
var destinations = new[]
|
||||
{
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
destinations[0].ConcurrentRequestCount++;
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
|
@ -127,10 +127,10 @@ public class LoadBalancingPoliciesTests : TestAutoMockBase
|
|||
{
|
||||
var destinations = new[]
|
||||
{
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
new DestinationState("d1"),
|
||||
new DestinationState("d2"),
|
||||
new DestinationState("d3")
|
||||
};
|
||||
destinations[0].ConcurrentRequestCount++;
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
|
|
|
@ -107,9 +107,9 @@ public class ProxyConfigManagerTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "d1", new DestinationConfig { Address = TestAddress } }
|
||||
}
|
||||
{
|
||||
{ "d1", new DestinationConfig { Address = TestAddress } }
|
||||
}
|
||||
};
|
||||
var route = new RouteConfig
|
||||
{
|
||||
|
@ -155,9 +155,9 @@ public class ProxyConfigManagerTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "d1", new DestinationConfig { Address = TestAddress } }
|
||||
},
|
||||
{
|
||||
{ "d1", new DestinationConfig { Address = TestAddress } }
|
||||
},
|
||||
HttpClient = new HttpClientConfig
|
||||
{
|
||||
SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12,
|
||||
|
@ -281,11 +281,11 @@ public class ProxyConfigManagerTests
|
|||
endpoints,
|
||||
new List<ClusterConfig>()
|
||||
{
|
||||
new ClusterConfig
|
||||
{
|
||||
ClusterId = "c1",
|
||||
HealthCheck = new HealthCheckConfig { Active = new ActiveHealthCheckConfig { Enabled = true } }
|
||||
}
|
||||
new ClusterConfig
|
||||
{
|
||||
ClusterId = "c1",
|
||||
HealthCheck = new HealthCheckConfig { Active = new ActiveHealthCheckConfig { Enabled = true } }
|
||||
}
|
||||
});
|
||||
await signaled.Task.DefaultTimeout();
|
||||
|
||||
|
@ -301,9 +301,9 @@ public class ProxyConfigManagerTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "d1", new DestinationConfig { Address = TestAddress } }
|
||||
},
|
||||
{
|
||||
{ "d1", new DestinationConfig { Address = TestAddress } }
|
||||
},
|
||||
HttpRequest = new ForwarderRequestConfig() { Version = new Version(1, 2) }
|
||||
};
|
||||
|
||||
|
@ -422,9 +422,9 @@ public class ProxyConfigManagerTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "d1", new DestinationConfig() { Address = "http://localhost" } }
|
||||
},
|
||||
{
|
||||
{ "d1", new DestinationConfig() { Address = "http://localhost" } }
|
||||
},
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
["Order"] = "47"
|
||||
|
@ -475,9 +475,9 @@ public class ProxyConfigManagerTests
|
|||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "d1", new DestinationConfig() { Address = "http://localhost" } }
|
||||
}
|
||||
{
|
||||
{ "d1", new DestinationConfig() { Address = "http://localhost" } }
|
||||
}
|
||||
};
|
||||
var services = CreateServices(new List<RouteConfig>(), new List<ClusterConfig>() { cluster }, proxyBuilder =>
|
||||
{
|
||||
|
|
|
@ -21,23 +21,23 @@ public class HeaderMatcherPolicyTests
|
|||
// Most specific to least
|
||||
var endpoints = new[]
|
||||
{
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)),
|
||||
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.ExactHeader)),
|
||||
(0, CreateEndpoint("header", new[] { "abc", "def" }, HeaderMatchMode.ExactHeader)),
|
||||
(0, CreateEndpoint("header2", new[] { "abc", "def" }, HeaderMatchMode.ExactHeader)),
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.ExactHeader)),
|
||||
(0, CreateEndpoint("header", new[] { "abc", "def" }, HeaderMatchMode.ExactHeader)),
|
||||
(0, CreateEndpoint("header2", new[] { "abc", "def" }, HeaderMatchMode.ExactHeader)),
|
||||
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.HeaderPrefix, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.HeaderPrefix, isCaseSensitive: true)),
|
||||
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.HeaderPrefix)),
|
||||
(0, CreateEndpoint("header", new[] { "abc", "def" }, HeaderMatchMode.HeaderPrefix)),
|
||||
(0, CreateEndpoint("header2", new[] { "abc", "def" }, HeaderMatchMode.HeaderPrefix)),
|
||||
(0, CreateEndpoint("header", new[] { "abc" }, HeaderMatchMode.HeaderPrefix)),
|
||||
(0, CreateEndpoint("header", new[] { "abc", "def" }, HeaderMatchMode.HeaderPrefix)),
|
||||
(0, CreateEndpoint("header2", new[] { "abc", "def" }, HeaderMatchMode.HeaderPrefix)),
|
||||
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists)),
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists)),
|
||||
};
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists)),
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("header", new string[0], HeaderMatchMode.Exists)),
|
||||
};
|
||||
var sut = new HeaderMatcherPolicy();
|
||||
|
||||
for (var i = 0; i < endpoints.Length; i++)
|
||||
|
@ -65,30 +65,30 @@ public class HeaderMatcherPolicyTests
|
|||
// Most specific to least
|
||||
var endpoints = new[]
|
||||
{
|
||||
(0, CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.HeaderPrefix, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "cbcabc" }, HeaderMatchMode.Contains, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})),
|
||||
(0, CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.HeaderPrefix, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "cbcabc" }, HeaderMatchMode.Contains, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})),
|
||||
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new[] { "cbcabc" }, HeaderMatchMode.Contains, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})),
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})),
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new[] { "cbcabc" }, HeaderMatchMode.Contains, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})),
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})),
|
||||
|
||||
(2, CreateEndpoint("header", new[] { "abc" })),
|
||||
(2, CreateEndpoint("header", new[] { "abc" })),
|
||||
|
||||
(3, CreateEndpoint(Array.Empty<HeaderMatcher>())),
|
||||
(3, CreateEndpoint(Array.Empty<HeaderMatcher>())),
|
||||
|
||||
};
|
||||
};
|
||||
var sut = new HeaderMatcherPolicy();
|
||||
|
||||
for (var i = 0; i < endpoints.Length; i++)
|
||||
|
@ -115,18 +115,18 @@ public class HeaderMatcherPolicyTests
|
|||
{
|
||||
var scenarios = new[]
|
||||
{
|
||||
CreateEndpoint("org-id", new string[0], HeaderMatchMode.Exists),
|
||||
CreateEndpoint("org-id", new[] { "abc" }),
|
||||
CreateEndpoint("org-id", new[] { "abc", "def" }),
|
||||
CreateEndpoint("org-id", new string[0], HeaderMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint("org-id", new[] { "abc" }, isDynamic: true),
|
||||
CreateEndpoint("org-id", null, HeaderMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})
|
||||
};
|
||||
CreateEndpoint("org-id", new string[0], HeaderMatchMode.Exists),
|
||||
CreateEndpoint("org-id", new[] { "abc" }),
|
||||
CreateEndpoint("org-id", new[] { "abc", "def" }),
|
||||
CreateEndpoint("org-id", new string[0], HeaderMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint("org-id", new[] { "abc" }, isDynamic: true),
|
||||
CreateEndpoint("org-id", null, HeaderMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header", new string[0], HeaderMatchMode.Exists, isCaseSensitive: true),
|
||||
new HeaderMatcher("header", new[] { "abc" }, HeaderMatchMode.ExactHeader, isCaseSensitive: true)
|
||||
})
|
||||
};
|
||||
var sut = new HeaderMatcherPolicy();
|
||||
var endpointSelectorPolicy = (IEndpointSelectorPolicy)sut;
|
||||
|
||||
|
@ -351,9 +351,9 @@ public class HeaderMatcherPolicyTests
|
|||
{
|
||||
var endpoint = CreateEndpoint(new[]
|
||||
{
|
||||
new HeaderMatcher("header1", new[] { "value1" }, HeaderMatchMode.ExactHeader, isCaseSensitive: false),
|
||||
new HeaderMatcher("header2", new[] { "value2" }, HeaderMatchMode.ExactHeader, isCaseSensitive: false)
|
||||
});
|
||||
new HeaderMatcher("header1", new[] { "value1" }, HeaderMatchMode.ExactHeader, isCaseSensitive: false),
|
||||
new HeaderMatcher("header2", new[] { "value2" }, HeaderMatchMode.ExactHeader, isCaseSensitive: false)
|
||||
});
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
if (sendHeader1)
|
||||
|
|
|
@ -429,14 +429,14 @@ public class ProxyEndpointFactoryTests
|
|||
Path = "/",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
IsCaseSensitive = true,
|
||||
}
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
IsCaseSensitive = true,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
var cluster = new ClusterState("cluster1");
|
||||
|
@ -474,19 +474,19 @@ public class ProxyEndpointFactoryTests
|
|||
Path = "/",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
IsCaseSensitive = true,
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header2",
|
||||
Mode = HeaderMatchMode.Exists,
|
||||
}
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
Mode = HeaderMatchMode.HeaderPrefix,
|
||||
IsCaseSensitive = true,
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header2",
|
||||
Mode = HeaderMatchMode.Exists,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
var cluster = new ClusterState("cluster1");
|
||||
|
|
|
@ -21,27 +21,27 @@ public class QueryParameterMatcherPolicyTests
|
|||
// Most specific to least
|
||||
var endpoints = new[]
|
||||
{
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)),
|
||||
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc", "def" }, QueryParameterMatchMode.Exact)),
|
||||
(0, CreateEndpoint("queryparam2", new[] { "abc", "def" }, QueryParameterMatchMode.Exact)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc", "def" }, QueryParameterMatchMode.Exact)),
|
||||
(0, CreateEndpoint("queryparam2", new[] { "abc", "def" }, QueryParameterMatchMode.Exact)),
|
||||
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains, isCaseSensitive: true)),
|
||||
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc", "def" }, QueryParameterMatchMode.Contains)),
|
||||
(0, CreateEndpoint("queryparam2", new[] { "abc", "def" }, QueryParameterMatchMode.Contains)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc", "def" }, QueryParameterMatchMode.Contains)),
|
||||
(0, CreateEndpoint("queryparam2", new[] { "abc", "def" }, QueryParameterMatchMode.Contains)),
|
||||
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Prefix)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc", "def" }, QueryParameterMatchMode.Prefix)),
|
||||
(0, CreateEndpoint("queryparam2", new[] { "abc", "def" }, QueryParameterMatchMode.Prefix)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc" }, QueryParameterMatchMode.Prefix)),
|
||||
(0, CreateEndpoint("queryparam", new[] { "abc", "def" }, QueryParameterMatchMode.Prefix)),
|
||||
(0, CreateEndpoint("queryparam2", new[] { "abc", "def" }, QueryParameterMatchMode.Prefix)),
|
||||
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists)),
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists)),
|
||||
};
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists)),
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true)),
|
||||
(0, CreateEndpoint("queryparam", new string[0], QueryParameterMatchMode.Exists)),
|
||||
};
|
||||
var sut = new QueryParameterMatcherPolicy();
|
||||
|
||||
for (var i = 0; i < endpoints.Length; i++)
|
||||
|
@ -69,31 +69,31 @@ public class QueryParameterMatcherPolicyTests
|
|||
// Most specific to least
|
||||
var endpoints = new[]
|
||||
{
|
||||
(0, CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Prefix, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
(0, CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Prefix, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
|
||||
})),
|
||||
})),
|
||||
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
})),
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
})),
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Contains, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
})),
|
||||
(1, CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryparam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryparam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
})),
|
||||
|
||||
(2, CreateEndpoint("queryparam", new[] { "abc" })),
|
||||
(2, CreateEndpoint("queryparam", new[] { "abc" })),
|
||||
|
||||
(3, CreateEndpoint(Array.Empty<QueryParameterMatcher>())),
|
||||
(3, CreateEndpoint(Array.Empty<QueryParameterMatcher>())),
|
||||
|
||||
};
|
||||
};
|
||||
var sut = new QueryParameterMatcherPolicy();
|
||||
|
||||
for (var i = 0; i < endpoints.Length; i++)
|
||||
|
@ -120,18 +120,18 @@ public class QueryParameterMatcherPolicyTests
|
|||
{
|
||||
var scenarios = new[]
|
||||
{
|
||||
CreateEndpoint("org-id", new string[0], QueryParameterMatchMode.Exists),
|
||||
CreateEndpoint("org-id", new[] { "abc" }),
|
||||
CreateEndpoint("org-id", new[] { "abc", "def" }),
|
||||
CreateEndpoint("org-id", new string[0], QueryParameterMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint("org-id", new[] { "abc" }, isDynamic: true),
|
||||
CreateEndpoint("org-id", null, QueryParameterMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryParam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryParam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
})
|
||||
};
|
||||
CreateEndpoint("org-id", new string[0], QueryParameterMatchMode.Exists),
|
||||
CreateEndpoint("org-id", new[] { "abc" }),
|
||||
CreateEndpoint("org-id", new[] { "abc", "def" }),
|
||||
CreateEndpoint("org-id", new string[0], QueryParameterMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint("org-id", new[] { "abc" }, isDynamic: true),
|
||||
CreateEndpoint("org-id", null, QueryParameterMatchMode.Exists, isDynamic: true),
|
||||
CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryParam", new string[0], QueryParameterMatchMode.Exists, isCaseSensitive: true),
|
||||
new QueryParameterMatcher("queryParam", new[] { "abc" }, QueryParameterMatchMode.Exact, isCaseSensitive: true)
|
||||
})
|
||||
};
|
||||
var sut = new QueryParameterMatcherPolicy();
|
||||
var endpointSelectorPolicy = (IEndpointSelectorPolicy)sut;
|
||||
|
||||
|
@ -358,9 +358,9 @@ public class QueryParameterMatcherPolicyTests
|
|||
{
|
||||
var endpoint = CreateEndpoint(new[]
|
||||
{
|
||||
new QueryParameterMatcher("queryParam1", new[] { "value1" }, QueryParameterMatchMode.Exact, isCaseSensitive: false),
|
||||
new QueryParameterMatcher("queryParam2", new[] { "value2" }, QueryParameterMatchMode.Exact, isCaseSensitive: false)
|
||||
});
|
||||
new QueryParameterMatcher("queryParam1", new[] { "value1" }, QueryParameterMatchMode.Exact, isCaseSensitive: false),
|
||||
new QueryParameterMatcher("queryParam2", new[] { "value2" }, QueryParameterMatchMode.Exact, isCaseSensitive: false)
|
||||
});
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
var queryStr = new List<string>();
|
||||
|
|
|
@ -25,13 +25,13 @@ public class RoutingTests
|
|||
{
|
||||
var routes = new[]
|
||||
{
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch { Path = "/api/{**catchall}" }
|
||||
}
|
||||
};
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch { Path = "/api/{**catchall}" }
|
||||
}
|
||||
};
|
||||
|
||||
using var host = await CreateHostAsync(routes);
|
||||
var client = host.GetTestClient();
|
||||
|
@ -51,13 +51,13 @@ public class RoutingTests
|
|||
{
|
||||
var routes = new[]
|
||||
{
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch { Hosts = new[] { "*.example.com" } }
|
||||
}
|
||||
};
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch { Hosts = new[] { "*.example.com" } }
|
||||
}
|
||||
};
|
||||
|
||||
using var host = await CreateHostAsync(routes);
|
||||
var client = host.GetTestClient();
|
||||
|
@ -77,24 +77,24 @@ public class RoutingTests
|
|||
{
|
||||
var routes = new[]
|
||||
{
|
||||
new RouteConfig()
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
new RouteHeader()
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
using var host = await CreateHostAsync(routes);
|
||||
var client = host.GetTestClient();
|
||||
|
@ -131,63 +131,63 @@ public class RoutingTests
|
|||
{
|
||||
var routes = new[]
|
||||
{
|
||||
new RouteConfig()
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
new RouteHeader()
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route2",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header2",
|
||||
Values = new[] { "value2" },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route3",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header2",
|
||||
Values = new[] { "value2" },
|
||||
}
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route2",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header2",
|
||||
Values = new[] { "value2" },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route3",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header2",
|
||||
Values = new[] { "value2" },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using var host = await CreateHostAsync(routes);
|
||||
var client = host.GetTestClient();
|
||||
|
@ -242,49 +242,49 @@ public class RoutingTests
|
|||
{
|
||||
var routes = new[]
|
||||
{
|
||||
new RouteConfig()
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch { Path = "/route1" }
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route2",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch { Path = "/route1" }
|
||||
},
|
||||
new RouteConfig()
|
||||
Path = "/{**catchall}",
|
||||
Methods = new[] { "GET" },
|
||||
}
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route3",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "route2",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
Hosts = new[] { "localhost" }
|
||||
}
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route4",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Methods = new[] { "GET" },
|
||||
}
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route3",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "localhost" }
|
||||
}
|
||||
},
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route4",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
Headers = new[]
|
||||
new RouteHeader()
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
},
|
||||
}
|
||||
Name = "header1",
|
||||
Values = new[] { "value1" },
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
using var host = await CreateHostAsync(routes);
|
||||
var client = host.GetTestClient();
|
||||
|
@ -324,15 +324,15 @@ public class RoutingTests
|
|||
{
|
||||
var clusters = new[]
|
||||
{
|
||||
new ClusterConfig()
|
||||
new ClusterConfig()
|
||||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
ClusterId = "cluster1",
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "d1", new DestinationConfig() { Address = "http://localhost/" } }
|
||||
}
|
||||
{ "d1", new DestinationConfig() { Address = "http://localhost/" } }
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return new HostBuilder()
|
||||
.ConfigureWebHost(webHost =>
|
||||
|
|
|
@ -167,7 +167,7 @@ public class BaseSesstionAffinityPolicyTests
|
|||
|
||||
public ProviderStub(IDataProtectionProvider dataProtectionProvider, ILogger logger)
|
||||
: base(dataProtectionProvider, logger)
|
||||
{ }
|
||||
{}
|
||||
|
||||
public override string Name => "Stub";
|
||||
|
||||
|
|
|
@ -53,10 +53,10 @@ public class SessionAffinityMiddlewareTests
|
|||
(expectedMode, status, foundDestination, p => invokedMode = p.Name));
|
||||
var nextInvoked = false;
|
||||
var middleware = new SessionAffinityMiddleware(c =>
|
||||
{
|
||||
nextInvoked = true;
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
{
|
||||
nextInvoked = true;
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
policies.Select(p => p.Object), new IAffinityFailurePolicy[0],
|
||||
new Mock<ILogger<SessionAffinityMiddleware>>().Object);
|
||||
var context = new DefaultHttpContext();
|
||||
|
@ -102,10 +102,10 @@ public class SessionAffinityMiddlewareTests
|
|||
var nextInvoked = false;
|
||||
var logger = AffinityTestHelper.GetLogger<SessionAffinityMiddleware>();
|
||||
var middleware = new SessionAffinityMiddleware(c =>
|
||||
{
|
||||
nextInvoked = true;
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
{
|
||||
nextInvoked = true;
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
policies.Select(p => p.Object), failurePolicies.Select(p => p.Object),
|
||||
logger.Object);
|
||||
var context = new DefaultHttpContext();
|
||||
|
|
|
@ -116,8 +116,8 @@ public class TransformBuilderTests
|
|||
var transformBuilder = CreateTransformBuilder();
|
||||
var transforms = new[]
|
||||
{
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase), // Empty
|
||||
};
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase), // Empty
|
||||
};
|
||||
|
||||
var route = new RouteConfig() { Transforms = transforms };
|
||||
var errors = transformBuilder.ValidateRoute(route);
|
||||
|
@ -134,17 +134,17 @@ public class TransformBuilderTests
|
|||
var transformBuilder = CreateTransformBuilder();
|
||||
var transforms = new[]
|
||||
{
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) // Unknown transform
|
||||
{
|
||||
{ "string1", "value1" },
|
||||
{ "string2", "value2" }
|
||||
},
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) // Unknown transform
|
||||
{
|
||||
{ "string3", "value3" },
|
||||
{ "string4", "value4" }
|
||||
},
|
||||
};
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) // Unknown transform
|
||||
{
|
||||
{ "string1", "value1" },
|
||||
{ "string2", "value2" }
|
||||
},
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) // Unknown transform
|
||||
{
|
||||
{ "string3", "value3" },
|
||||
{ "string4", "value4" }
|
||||
},
|
||||
};
|
||||
|
||||
var route = new RouteConfig() { Transforms = transforms };
|
||||
var errors = transformBuilder.ValidateRoute(route);
|
||||
|
@ -221,15 +221,15 @@ public class TransformBuilderTests
|
|||
var transformBuilder = CreateTransformBuilder();
|
||||
var transforms = new[]
|
||||
{
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeadersCopy", "false" }
|
||||
},
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "X-Forwarded", "Off" }
|
||||
},
|
||||
};
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeadersCopy", "false" }
|
||||
},
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "X-Forwarded", "Off" }
|
||||
},
|
||||
};
|
||||
|
||||
var route = new RouteConfig() { Transforms = transforms };
|
||||
var errors = transformBuilder.ValidateRoute(route);
|
||||
|
@ -259,22 +259,22 @@ public class TransformBuilderTests
|
|||
var transforms = new List<Dictionary<string, string>>();
|
||||
// Disable default forwarders
|
||||
transforms.Add(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "X-Forwarded", "Off" }
|
||||
});
|
||||
{
|
||||
{ "X-Forwarded", "Off" }
|
||||
});
|
||||
if (useOriginalHost.HasValue)
|
||||
{
|
||||
transforms.Add(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeaderOriginalHost", useOriginalHost.ToString() }
|
||||
});
|
||||
{
|
||||
{ "RequestHeaderOriginalHost", useOriginalHost.ToString() }
|
||||
});
|
||||
}
|
||||
if (copyHeaders.HasValue)
|
||||
{
|
||||
transforms.Add(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeadersCopy", copyHeaders.ToString() }
|
||||
});
|
||||
{
|
||||
{ "RequestHeadersCopy", copyHeaders.ToString() }
|
||||
});
|
||||
}
|
||||
|
||||
var route = new RouteConfig() { Transforms = transforms };
|
||||
|
@ -339,27 +339,27 @@ public class TransformBuilderTests
|
|||
var transforms = new List<Dictionary<string, string>>();
|
||||
// Disable default forwarders
|
||||
transforms.Add(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "X-Forwarded", "Off" }
|
||||
});
|
||||
{
|
||||
{ "X-Forwarded", "Off" }
|
||||
});
|
||||
transforms.Add(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeader", "Host" },
|
||||
{ "Set", "CustomHost" }
|
||||
});
|
||||
{
|
||||
{ "RequestHeader", "Host" },
|
||||
{ "Set", "CustomHost" }
|
||||
});
|
||||
if (useOriginalHost.HasValue)
|
||||
{
|
||||
transforms.Add(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeaderOriginalHost", useOriginalHost.ToString() }
|
||||
});
|
||||
{
|
||||
{ "RequestHeaderOriginalHost", useOriginalHost.ToString() }
|
||||
});
|
||||
}
|
||||
if (copyHeaders.HasValue)
|
||||
{
|
||||
transforms.Add(new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeadersCopy", copyHeaders.ToString() }
|
||||
});
|
||||
{
|
||||
{ "RequestHeadersCopy", copyHeaders.ToString() }
|
||||
});
|
||||
}
|
||||
|
||||
var route = new RouteConfig() { Transforms = transforms };
|
||||
|
@ -385,15 +385,15 @@ public class TransformBuilderTests
|
|||
var transformBuilder = CreateTransformBuilder();
|
||||
var transforms = new[]
|
||||
{
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeadersCopy", "false" }
|
||||
},
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "Forwarded", "proto" }
|
||||
},
|
||||
};
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "RequestHeadersCopy", "false" }
|
||||
},
|
||||
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "Forwarded", "proto" }
|
||||
},
|
||||
};
|
||||
|
||||
var route = new RouteConfig() { Transforms = transforms };
|
||||
var errors = transformBuilder.ValidateRoute(route);
|
||||
|
|
|
@ -95,8 +95,8 @@ public class ForwardedTransformExtensionsTests : TransformExtentionsTestsBase
|
|||
var actions = (ForwardedTransformActions[])Enum.GetValues(typeof(ForwardedTransformActions));
|
||||
var addTransformFuncs = new (Func<TransformBuilderContext, string, ForwardedTransformActions, TransformBuilderContext>, string)[]
|
||||
{
|
||||
(ForwardedTransformExtensions.AddXForwardedFor, "For"), (ForwardedTransformExtensions.AddXForwardedPrefix, "Prefix"),
|
||||
(ForwardedTransformExtensions.AddXForwardedHost, "Host"), (ForwardedTransformExtensions.AddXForwardedProto, "Proto")
|
||||
(ForwardedTransformExtensions.AddXForwardedFor, "For"), (ForwardedTransformExtensions.AddXForwardedPrefix, "Prefix"),
|
||||
(ForwardedTransformExtensions.AddXForwardedHost, "Host"), (ForwardedTransformExtensions.AddXForwardedProto, "Proto")
|
||||
};
|
||||
|
||||
return addTransformFuncs.Join(actions, _ => true, _ => true, (t, a) => new object[] { t.Item1, t.Item2, a });
|
||||
|
|
|
@ -25,11 +25,11 @@ public class PathRouteValuesTransformTests
|
|||
using var services = serviceCollection.BuildServiceProvider();
|
||||
|
||||
var routeValues = new Dictionary<string, object>
|
||||
{
|
||||
{ "a", "6" },
|
||||
{ "b", "7" },
|
||||
{ "c", "8" },
|
||||
};
|
||||
{
|
||||
{ "a", "6" },
|
||||
{ "b", "7" },
|
||||
{ "c", "8" },
|
||||
};
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.RouteValues = new RouteValueDictionary(routeValues);
|
||||
|
@ -55,11 +55,11 @@ public class PathRouteValuesTransformTests
|
|||
using var services = serviceCollection.BuildServiceProvider();
|
||||
|
||||
var routeValues = new Dictionary<string, object>
|
||||
{
|
||||
{ "a", "abc" },
|
||||
{ "b", "def" },
|
||||
{ "remainder", "klm/nop/qrs" },
|
||||
};
|
||||
{
|
||||
{ "a", "abc" },
|
||||
{ "b", "def" },
|
||||
{ "remainder", "klm/nop/qrs" },
|
||||
};
|
||||
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.RouteValues = new RouteValueDictionary(routeValues);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -58,19 +58,19 @@ internal static class SFTestHelpers
|
|||
internal static Dictionary<string, string> DummyLabels(string backendId, bool enableGateway = true, bool activeHealthChecks = false)
|
||||
{
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Enable", enableGateway ? "true" : "false" },
|
||||
{ "YARP.Backend.BackendId", backendId },
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", activeHealthChecks ? "true" : "false" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", "5" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Timeout", "5" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Port", "8787" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Path", "/api/health" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Policy", "ConsecutiveFailures" },
|
||||
{ "YARP.Metadata.Foo", "Bar" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Enable", enableGateway ? "true" : "false" },
|
||||
{ "YARP.Backend.BackendId", backendId },
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", activeHealthChecks ? "true" : "false" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", "5" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Timeout", "5" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Port", "8787" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Path", "/api/health" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Policy", "ConsecutiveFailures" },
|
||||
{ "YARP.Metadata.Foo", "Bar" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -100,9 +100,9 @@ internal static class SFTestHelpers
|
|||
Health = healthAddressUri,
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "PartitionId", partition.Id.ToString() ?? string.Empty },
|
||||
{ "NamedPartitionName", partition.Name ?? string.Empty },
|
||||
{ "ReplicaId", replica.Id.ToString() ?? string.Empty }
|
||||
{ "PartitionId", partition.Id.ToString() ?? string.Empty },
|
||||
{ "NamedPartitionName", partition.Name ?? string.Empty },
|
||||
{ "ReplicaId", replica.Id.ToString() ?? string.Empty }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -115,12 +115,12 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[3], partitions[1])),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[3], partitions[1])),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
|
@ -148,12 +148,12 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[3], partitions[1])),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[3], partitions[1])),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
|
@ -185,13 +185,13 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels1,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica1, partition1)),
|
||||
ClusterWithDestinations(_testServiceName, labels2,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica2, partition2)),
|
||||
ClusterWithDestinations(_testServiceName, labels3,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica3, partition3)),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels1,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica1, partition1)),
|
||||
ClusterWithDestinations(_testServiceName, labels2,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica2, partition2)),
|
||||
ClusterWithDestinations(_testServiceName, labels3,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica3, partition3)),
|
||||
};
|
||||
var expectedRoutes = new List<RouteConfig>();
|
||||
expectedRoutes.AddRange(LabelsParser.BuildRoutes(_testServiceName, labels1));
|
||||
expectedRoutes.AddRange(LabelsParser.BuildRoutes(_testServiceName, labels2));
|
||||
|
@ -228,9 +228,9 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, gatewayEnabledLabels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica1, partition1)),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, gatewayEnabledLabels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica1, partition1)),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, gatewayEnabledLabels);
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -285,12 +285,12 @@ public class DiscovererTests : TestAutoMockBase
|
|||
{
|
||||
_scenarioOptions = new ServiceFabricDiscoveryOptions { ReportReplicasHealth = true };
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.Backend.BackendId", "SomeClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "not a number" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.Backend.BackendId", "SomeClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "not a number" },
|
||||
};
|
||||
ApplicationWrapper application;
|
||||
Mock_AppsResponse(
|
||||
application = CreateApp_1Service_SingletonPartition_1Replica("MyApp", "MyService", out var service, out var replica, out var partition));
|
||||
|
@ -301,9 +301,9 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
|
||||
};
|
||||
var expectedRoutes = new List<RouteConfig>();
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -330,8 +330,8 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -360,8 +360,8 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -392,8 +392,8 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -423,9 +423,9 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition, "ExampleTeamHealthEndpoint")),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition, "ExampleTeamHealthEndpoint")),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -468,11 +468,11 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1])),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[0], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[1], partitions[0]),
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replicas[2], partitions[1])),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -499,9 +499,9 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
|
||||
};
|
||||
var expectedRoutes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
|
@ -535,9 +535,9 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
|
||||
};
|
||||
ClusterWithDestinations(_testServiceName, labels,
|
||||
SFTestHelpers.BuildDestinationFromReplicaAndPartition(replica, partition)),
|
||||
};
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
_healthReports.Should().HaveCount(2);
|
||||
|
@ -568,8 +568,8 @@ public class DiscovererTests : TestAutoMockBase
|
|||
|
||||
var expectedClusters = new[]
|
||||
{
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
LabelsParser.BuildCluster(_testServiceName, labels, new Dictionary<string, DestinationConfig>()),
|
||||
};
|
||||
|
||||
clusters.Should().BeEquivalentTo(expectedClusters);
|
||||
_healthReports.Should().HaveCount(1);
|
||||
|
|
|
@ -57,11 +57,11 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='AnotherService'>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='AnotherService'>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
||||
|
@ -74,11 +74,11 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
||||
|
@ -90,23 +90,23 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
<StatelessServiceType ServiceTypeName='AnotherServiceType'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
<StatelessServiceType ServiceTypeName='AnotherServiceType'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
||||
|
@ -118,19 +118,19 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='AnotherExtension'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='Bla'>foo</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='AnotherExtension'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='Bla'>foo</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
||||
|
@ -142,28 +142,28 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.foo'>bar</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.foo'>bar</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
||||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.foo", "bar" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.foo", "bar" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -172,19 +172,19 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.foo'>[SomeAppParam]</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.foo'>[SomeAppParam]</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
|
||||
_appParams["someAppParam"] = "replaced successfully!";
|
||||
|
||||
|
@ -193,8 +193,8 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.foo", "replaced successfully!" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.foo", "replaced successfully!" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -203,27 +203,27 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.foo'>[NonExistingAppParam]</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.foo'>[NonExistingAppParam]</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>";
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
||||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.foo", string.Empty },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.foo", string.Empty },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -232,33 +232,33 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='AnotherExtension'>
|
||||
<Labels>
|
||||
<Label Key='NotThisONe'>I said not this one</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.routes.route1.Hosts'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='AnotherExtension'>
|
||||
<Labels>
|
||||
<Label Key='NotThisONe'>I said not this one</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.routes.route1.Hosts'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
||||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -267,24 +267,24 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -292,9 +292,9 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -303,24 +303,24 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>True</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>True</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -328,9 +328,9 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "True" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "True" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -339,25 +339,25 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARp.Enable", "false" },
|
||||
{ "WhatIsThisNamespace.value", "42" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARp.Enable", "false" },
|
||||
{ "WhatIsThisNamespace.value", "42" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -365,8 +365,8 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -375,25 +375,25 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
<Label Key='YARP.routes.route1.Hosts'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
<Label Key='YARP.routes.route1.Hosts'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "false" },
|
||||
{ "YARP.Enable", "false" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -401,9 +401,9 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "false" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
{ "YARP.Enable", "false" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -412,25 +412,25 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
<Label Key='YARP.routes.route1.Hosts'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
<Label Key='YARP.routes.route1.Hosts'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Routes.route1.HOST", "another.example.com" },
|
||||
{ "YARP.Routes.route1.HOST", "another.example.com" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -438,10 +438,10 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
{ "YARP.Routes.route1.HOST", "another.example.com" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.Hosts", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
{ "YARP.Routes.route1.HOST", "another.example.com" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -450,25 +450,25 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>false</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>false</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "false" },
|
||||
{ "YARP.Enable", "false" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -476,9 +476,9 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.host", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "false" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.host", "example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "false" },
|
||||
});
|
||||
|
||||
Mock<ICachedServiceFabricCaller>().Verify(m => m.EnumeratePropertiesAsync(It.IsAny<Uri>(), It.IsAny<CancellationToken>()), Times.Never());
|
||||
|
@ -489,26 +489,26 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
<Label Key='YARP.routes.ROUTE1.Hosts'>example.com</Label>
|
||||
<Label Key='YARP.routes.route1.hosts'>another.example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.EnableDynamicOverrides'>true</Label>
|
||||
<Label Key='YARP.routes.ROUTE1.Hosts'>example.com</Label>
|
||||
<Label Key='YARP.routes.route1.hosts'>another.example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.routes.Route1.HOSTS", "etc.example.com" },
|
||||
{ "YARP.routes.Route1.HOSTS", "etc.example.com" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -516,11 +516,11 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.ROUTE1.Hosts", "example.com" },
|
||||
{ "YARP.routes.route1.hosts", "another.example.com" },
|
||||
{ "YARP.routes.Route1.HOSTS", "etc.example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.ROUTE1.Hosts", "example.com" },
|
||||
{ "YARP.routes.route1.hosts", "another.example.com" },
|
||||
{ "YARP.routes.Route1.HOSTS", "etc.example.com" },
|
||||
{ "YARP.EnableDynamicOverrides", "true" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -529,24 +529,24 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
_namingServiceProperties =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "false" },
|
||||
{ "YARP.Enable", "false" },
|
||||
};
|
||||
|
||||
var labels = await RunScenarioAsync();
|
||||
|
@ -554,8 +554,8 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
labels.Should().Equal(
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.host", "example.com" },
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.routes.route1.host", "example.com" },
|
||||
});
|
||||
|
||||
Mock<ICachedServiceFabricCaller>().Verify(m => m.EnumeratePropertiesAsync(It.IsAny<Uri>(), It.IsAny<CancellationToken>()), Times.Never());
|
||||
|
@ -576,21 +576,21 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatefulService ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.Enable'>true</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
<Label Key='YARP.routes.route1.host'>example.com</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatefulService>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
|
||||
Func<Task> func = () => RunScenarioAsync();
|
||||
|
||||
|
@ -603,19 +603,19 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
var longBadString = new string('*', 1024 * 1024);
|
||||
_rawServiceManifest =
|
||||
$@"<ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.foo'>'{longBadString}'</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.foo'>'{longBadString}'</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
|
||||
Func<Task> func = () => RunScenarioAsync();
|
||||
|
||||
|
@ -627,23 +627,23 @@ public class ServiceExtensionLabelsProviderTests : TestAutoMockBase
|
|||
{
|
||||
_rawServiceManifest =
|
||||
$@"
|
||||
<!DOCTYPE xxe [
|
||||
<!ENTITY chybeta ""Melicious DTD value here."">
|
||||
]>
|
||||
< ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.foo'>bar</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
<!DOCTYPE xxe [
|
||||
<!ENTITY chybeta ""Melicious DTD value here."">
|
||||
]>
|
||||
< ServiceManifest xmlns='{ServiceExtensionLabelsProvider.XNSServiceManifest}'>
|
||||
<ServiceTypes>
|
||||
<StatelessServiceType ServiceTypeName='{ServiceTypeName}'>
|
||||
<Extensions>
|
||||
<Extension Name='YARP-preview'>
|
||||
<Labels xmlns='{ServiceExtensionLabelsProvider.XNSFabricNoSchema}'>
|
||||
<Label Key='YARP.foo'>bar</Label>
|
||||
</Labels>
|
||||
</Extension>
|
||||
</Extensions>
|
||||
</StatelessServiceType>
|
||||
</ServiceTypes>
|
||||
</ServiceManifest>
|
||||
";
|
||||
|
||||
Func<Task> func = () => RunScenarioAsync();
|
||||
|
||||
|
|
|
@ -20,14 +20,14 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "https://localhost:123/valid";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -48,13 +48,13 @@ public class FabricServiceEndpointSelectorTests
|
|||
var allowedScheme = "https";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'SelectedServiceEndpoint': 'https://localhost:123/selected',
|
||||
'notSelected1': 'https://loopback:123/query',
|
||||
'notSelected2': 'https://localhost:456/query',
|
||||
'notSelected3': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'SelectedServiceEndpoint': 'https://localhost:123/selected',
|
||||
'notSelected1': 'https://loopback:123/query',
|
||||
'notSelected2': 'https://localhost:456/query',
|
||||
'notSelected3': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { string.Empty },
|
||||
allowedSchemePredicate: (scheme) => scheme == allowedScheme,
|
||||
|
@ -76,14 +76,14 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "https://localhost:123/valid";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -105,13 +105,13 @@ public class FabricServiceEndpointSelectorTests
|
|||
var allowedScheme = "https";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -134,14 +134,14 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "https://localhost:123/valid";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': 'https://localhost:123/query',
|
||||
'DifferentServiceEndpoint2': 'https://loopback:123/query',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': 'https://localhost:456/query',
|
||||
'DifferentServiceEndpoint4': 'https://loopback:456/query'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -164,14 +164,14 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "https://localhost:123/valid";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -194,14 +194,14 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "https://localhost:123/valid";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'ValidServiceEndpoint': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'ValidServiceEndpoint': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -224,12 +224,12 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "https://localhost:123/valid";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'ServiceEndpointSecure': 'http://localhost/invalidScheme',
|
||||
'ValidServiceEndpoint': '{endpointAddress}'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'ServiceEndpointSecure': 'http://localhost/invalidScheme',
|
||||
'ValidServiceEndpoint': '{endpointAddress}'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: listenerNames,
|
||||
|
@ -251,11 +251,11 @@ public class FabricServiceEndpointSelectorTests
|
|||
var allowedScheme = "https";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'{listenerName}': 'http://localhost/invalidScheme',
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'{listenerName}': 'http://localhost/invalidScheme',
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -278,14 +278,14 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "/alsoMalformed";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
@ -308,14 +308,14 @@ public class FabricServiceEndpointSelectorTests
|
|||
var endpointAddress = "/alsoMalformed";
|
||||
|
||||
var endpoints = $@"{{
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
'Endpoints': {{
|
||||
'DifferentServiceEndpoint1': '/malformed',
|
||||
'DifferentServiceEndpoint2': '/malformed',
|
||||
'{listenerName}': '{endpointAddress}',
|
||||
'DifferentServiceEndpoint3': '/malformed',
|
||||
'DifferentServiceEndpoint4': '/malformed'
|
||||
}}
|
||||
}}".Replace("'", "\"");
|
||||
|
||||
var fabricServiceEndpoint = new FabricServiceEndpoint(
|
||||
listenerNames: new[] { listenerName },
|
||||
|
|
|
@ -21,49 +21,49 @@ public class LabelsParserTests
|
|||
public void BuildCluster_CompleteLabels_Works()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.LoadBalancingPolicy", "LeastRequests" },
|
||||
{ "YARP.Backend.SessionAffinity.Enabled", "true" },
|
||||
{ "YARP.Backend.SessionAffinity.Policy", "Cookie" },
|
||||
{ "YARP.Backend.SessionAffinity.FailurePolicy", "Return503Error" },
|
||||
{ "YARP.Backend.SessionAffinity.AffinityKeyName", "Key1" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.Domain", "localhost" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.Expiration", "03:00:00" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.HttpOnly", "true" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.IsEssential", "true" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.MaxAge", "1.00:00:00" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.Path", "mypath" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.SameSite", "Strict" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.SecurePolicy", "SameAsRequest" },
|
||||
{ "YARP.Backend.HttpRequest.ActivityTimeout", "00:00:17" },
|
||||
{ "YARP.Backend.HttpRequest.AllowResponseBuffering", "true" },
|
||||
{ "YARP.Backend.HttpRequest.Version", "1.1" },
|
||||
{
|
||||
{ "YARP.Enable", "true" },
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.LoadBalancingPolicy", "LeastRequests" },
|
||||
{ "YARP.Backend.SessionAffinity.Enabled", "true" },
|
||||
{ "YARP.Backend.SessionAffinity.Policy", "Cookie" },
|
||||
{ "YARP.Backend.SessionAffinity.FailurePolicy", "Return503Error" },
|
||||
{ "YARP.Backend.SessionAffinity.AffinityKeyName", "Key1" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.Domain", "localhost" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.Expiration", "03:00:00" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.HttpOnly", "true" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.IsEssential", "true" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.MaxAge", "1.00:00:00" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.Path", "mypath" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.SameSite", "Strict" },
|
||||
{ "YARP.Backend.SessionAffinity.Cookie.SecurePolicy", "SameAsRequest" },
|
||||
{ "YARP.Backend.HttpRequest.ActivityTimeout", "00:00:17" },
|
||||
{ "YARP.Backend.HttpRequest.AllowResponseBuffering", "true" },
|
||||
{ "YARP.Backend.HttpRequest.Version", "1.1" },
|
||||
#if NET
|
||||
{ "YARP.Backend.HttpRequest.VersionPolicy", "RequestVersionExact" },
|
||||
{ "YARP.Backend.HttpRequest.VersionPolicy", "RequestVersionExact" },
|
||||
#endif
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", "true" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", "00:00:05" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Timeout", "00:00:06" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Policy", "MyActiveHealthPolicy" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Path", "/api/health" },
|
||||
{ "YARP.Backend.HealthCheck.Passive.Enabled", "true" },
|
||||
{ "YARP.Backend.HealthCheck.Passive.Policy", "MyPassiveHealthPolicy" },
|
||||
{ "YARP.Backend.HealthCheck.Passive.ReactivationPeriod", "00:00:07" },
|
||||
{ "YARP.Backend.Metadata.Foo", "Bar" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", "true" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", "00:00:05" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Timeout", "00:00:06" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Policy", "MyActiveHealthPolicy" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Path", "/api/health" },
|
||||
{ "YARP.Backend.HealthCheck.Passive.Enabled", "true" },
|
||||
{ "YARP.Backend.HealthCheck.Passive.Policy", "MyPassiveHealthPolicy" },
|
||||
{ "YARP.Backend.HealthCheck.Passive.ReactivationPeriod", "00:00:07" },
|
||||
{ "YARP.Backend.Metadata.Foo", "Bar" },
|
||||
|
||||
{ "YARP.Backend.HttpClient.DangerousAcceptAnyServerCertificate", "true" },
|
||||
{ "YARP.Backend.HttpClient.MaxConnectionsPerServer", "1000" },
|
||||
{ "YARP.Backend.HttpClient.SslProtocols", "Tls12" },
|
||||
{ "YARP.Backend.HttpClient.DangerousAcceptAnyServerCertificate", "true" },
|
||||
{ "YARP.Backend.HttpClient.MaxConnectionsPerServer", "1000" },
|
||||
{ "YARP.Backend.HttpClient.SslProtocols", "Tls12" },
|
||||
#if NET
|
||||
{ "YARP.Backend.HttpClient.EnableMultipleHttp2Connections", "false" },
|
||||
{ "YARP.Backend.HttpClient.RequestHeaderEncoding", "utf-8" },
|
||||
{ "YARP.Backend.HttpClient.EnableMultipleHttp2Connections", "false" },
|
||||
{ "YARP.Backend.HttpClient.RequestHeaderEncoding", "utf-8" },
|
||||
#endif
|
||||
{ "YARP.Backend.HttpClient.WebProxy.Address", "https://10.20.30.40" },
|
||||
{ "YARP.Backend.HttpClient.WebProxy.BypassOnLocal", "true" },
|
||||
{ "YARP.Backend.HttpClient.WebProxy.UseDefaultCredentials", "false" },
|
||||
};
|
||||
{ "YARP.Backend.HttpClient.WebProxy.Address", "https://10.20.30.40" },
|
||||
{ "YARP.Backend.HttpClient.WebProxy.BypassOnLocal", "true" },
|
||||
{ "YARP.Backend.HttpClient.WebProxy.UseDefaultCredentials", "false" },
|
||||
};
|
||||
|
||||
var cluster = LabelsParser.BuildCluster(_testServiceName, labels, null);
|
||||
|
||||
|
@ -116,9 +116,9 @@ public class LabelsParserTests
|
|||
}
|
||||
},
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "Foo", "Bar" },
|
||||
},
|
||||
{
|
||||
{ "Foo", "Bar" },
|
||||
},
|
||||
HttpClient = new HttpClientConfig
|
||||
{
|
||||
DangerousAcceptAnyServerCertificate = true,
|
||||
|
@ -143,10 +143,10 @@ public class LabelsParserTests
|
|||
public void BuildCluster_IncompleteLabels_UsesDefaultValues()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.SessionAffinity.AffinityKeyName", "Key1" }
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.SessionAffinity.AffinityKeyName", "Key1" }
|
||||
};
|
||||
|
||||
var cluster = LabelsParser.BuildCluster(_testServiceName, labels, null);
|
||||
|
||||
|
@ -187,10 +187,10 @@ public class LabelsParserTests
|
|||
public void BuildCluster_HealthCheckOptions_Enabled_Valid(string label, bool? expected)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", label },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", label },
|
||||
};
|
||||
|
||||
var cluster = LabelsParser.BuildCluster(_testServiceName, labels, null);
|
||||
|
||||
|
@ -203,10 +203,10 @@ public class LabelsParserTests
|
|||
public void BuildCluster_HealthCheckOptions_Enabled_Invalid(string label)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", label },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Enabled", label },
|
||||
};
|
||||
|
||||
Action action = () => LabelsParser.BuildCluster(_testServiceName, labels, null);
|
||||
|
||||
|
@ -217,13 +217,13 @@ public class LabelsParserTests
|
|||
public void BuildCluster_MissingBackendId_UsesServiceName()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.Quota.Burst", "2.3" },
|
||||
{ "YARP.Backend.Partitioning.Count", "5" },
|
||||
{ "YARP.Backend.Partitioning.KeyExtractor", "Header('x-ms-organization-id')" },
|
||||
{ "YARP.Backend.Partitioning.Algorithm", "SHA256" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", "00:00:5" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.Quota.Burst", "2.3" },
|
||||
{ "YARP.Backend.Partitioning.Count", "5" },
|
||||
{ "YARP.Backend.Partitioning.KeyExtractor", "Header('x-ms-organization-id')" },
|
||||
{ "YARP.Backend.Partitioning.Algorithm", "SHA256" },
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", "00:00:5" },
|
||||
};
|
||||
|
||||
var cluster = LabelsParser.BuildCluster(_testServiceName, labels, null);
|
||||
|
||||
|
@ -236,9 +236,9 @@ public class LabelsParserTests
|
|||
public void BuildCluster_NullTimespan(string value)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", value },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.HealthCheck.Active.Interval", value },
|
||||
};
|
||||
|
||||
var cluster = LabelsParser.BuildCluster(_testServiceName, labels, null);
|
||||
|
||||
|
@ -251,10 +251,10 @@ public class LabelsParserTests
|
|||
public void BuildCluster_InvalidValues_Throws(string key, string invalidValue)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ key, invalidValue },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ key, invalidValue },
|
||||
};
|
||||
|
||||
Func<ClusterConfig> func = () => LabelsParser.BuildCluster(_testServiceName, labels, null);
|
||||
|
||||
|
@ -265,77 +265,77 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_SingleRoute_Works()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "2" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].Mode", "ExactHeader" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].Name", "x-company-key" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].Values", "contoso" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].IsCaseSensitive", "true" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[1].Mode", "ExactHeader" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[1].Name", "x-environment" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[1].Values", "dev, uat" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[0].ResponseHeader", "X-Foo" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[0].Append", "Bar" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[0].When", "Always" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[1].ResponseHeader", "X-Ping" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[1].Append", "Pong" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[1].When", "Success" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "2" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].Mode", "ExactHeader" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].Name", "x-company-key" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].Values", "contoso" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[0].IsCaseSensitive", "true" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[1].Mode", "ExactHeader" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[1].Name", "x-environment" },
|
||||
{ "YARP.Routes.MyRoute.MatchHeaders.[1].Values", "dev, uat" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[0].ResponseHeader", "X-Foo" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[0].Append", "Bar" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[0].When", "Always" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[1].ResponseHeader", "X-Ping" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[1].Append", "Pong" },
|
||||
{ "YARP.Routes.MyRoute.Transforms.[1].When", "Success" },
|
||||
};
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
Hosts = new[] { "example.com" },
|
||||
Headers = new List<RouteHeader>
|
||||
{
|
||||
Hosts = new[] { "example.com" },
|
||||
Headers = new List<RouteHeader>
|
||||
new RouteHeader()
|
||||
{
|
||||
new RouteHeader()
|
||||
{
|
||||
Mode = HeaderMatchMode.ExactHeader,
|
||||
Name = "x-company-key",
|
||||
Values = new string[]{"contoso"},
|
||||
IsCaseSensitive = true
|
||||
},
|
||||
new RouteHeader()
|
||||
{
|
||||
Mode = HeaderMatchMode.ExactHeader,
|
||||
Name = "x-environment",
|
||||
Values = new string[]{"dev", "uat"},
|
||||
IsCaseSensitive = false
|
||||
}
|
||||
}
|
||||
},
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "Foo", "Bar" },
|
||||
},
|
||||
Transforms = new List<IReadOnlyDictionary<string, string>>
|
||||
{
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{"ResponseHeader", "X-Foo"},
|
||||
{"Append", "Bar"},
|
||||
{"When", "Always"}
|
||||
Mode = HeaderMatchMode.ExactHeader,
|
||||
Name = "x-company-key",
|
||||
Values = new string[]{"contoso"},
|
||||
IsCaseSensitive = true
|
||||
},
|
||||
new Dictionary<string, string>
|
||||
new RouteHeader()
|
||||
{
|
||||
{"ResponseHeader", "X-Ping"},
|
||||
{"Append", "Pong"},
|
||||
{"When", "Success"}
|
||||
Mode = HeaderMatchMode.ExactHeader,
|
||||
Name = "x-environment",
|
||||
Values = new string[]{"dev", "uat"},
|
||||
IsCaseSensitive = false
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "Foo", "Bar" },
|
||||
},
|
||||
Transforms = new List<IReadOnlyDictionary<string, string>>
|
||||
{
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{"ResponseHeader", "X-Foo"},
|
||||
{"Append", "Bar"},
|
||||
{"When", "Always"}
|
||||
},
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{"ResponseHeader", "X-Ping"},
|
||||
{"Append", "Pong"},
|
||||
{"When", "Success"}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -343,26 +343,26 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_IncompleteRoute_UsesDefaults()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
};
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
};
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -373,26 +373,26 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_SingleRouteWithSemanticallyInvalidRule_WorksAndDoesNotThrow()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "'this invalid thing" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "'this invalid thing" },
|
||||
};
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "'this invalid thing" },
|
||||
},
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
Hosts = new[] { "'this invalid thing" },
|
||||
},
|
||||
};
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -402,10 +402,10 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_MissingBackendId_UsesServiceName(int scenario)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "2" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "2" },
|
||||
};
|
||||
|
||||
if (scenario == 1)
|
||||
{
|
||||
|
@ -415,19 +415,19 @@ public class LabelsParserTests
|
|||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = $"{Uri.EscapeDataString(_testServiceName.ToString())}:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = $"{Uri.EscapeDataString(_testServiceName.ToString())}:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
Order = 2,
|
||||
ClusterId = _testServiceName.ToString(),
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
};
|
||||
Order = 2,
|
||||
ClusterId = _testServiceName.ToString(),
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -435,25 +435,25 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_MissingHost_Works()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Routes.MyRoute.Path", "/{**catchall}" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Routes.MyRoute.Path", "/{**catchall}" },
|
||||
};
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = $"{Uri.EscapeDataString(_testServiceName.ToString())}:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = $"{Uri.EscapeDataString(_testServiceName.ToString())}:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "/{**catchall}",
|
||||
},
|
||||
ClusterId = _testServiceName.ToString(),
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
Path = "/{**catchall}",
|
||||
},
|
||||
};
|
||||
ClusterId = _testServiceName.ToString(),
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -461,11 +461,11 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_InvalidOrder_Throws()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "this is no number" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "this is no number" },
|
||||
};
|
||||
|
||||
Func<List<RouteConfig>> func = () => LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
|
@ -483,28 +483,28 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_ValidRouteName_Works(string routeName)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ $"YARP.Routes.{routeName}.Hosts", "example.com" },
|
||||
{ $"YARP.Routes.{routeName}.Order", "2" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ $"YARP.Routes.{routeName}.Hosts", "example.com" },
|
||||
{ $"YARP.Routes.{routeName}.Order", "2" },
|
||||
};
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = $"MyCoolClusterId:{routeName}",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = $"MyCoolClusterId:{routeName}",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
};
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -521,12 +521,12 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_InvalidRouteName_Throws(string invalidKey, string value)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
labels[invalidKey] = value;
|
||||
|
||||
Func<List<RouteConfig>> func = () => LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
@ -543,12 +543,12 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_InvalidTransformIndex_Throws(string invalidKey, string value)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
labels[invalidKey] = value;
|
||||
|
||||
Func<List<RouteConfig>> func = () => LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
@ -566,12 +566,12 @@ public class LabelsParserTests
|
|||
{
|
||||
// Arrange
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
labels[invalidKey] = value;
|
||||
|
||||
// Act
|
||||
|
@ -589,12 +589,12 @@ public class LabelsParserTests
|
|||
{
|
||||
// Arrange
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Priority", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
labels[invalidKey] = value;
|
||||
|
||||
// Act
|
||||
|
@ -612,35 +612,35 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_MatchHeadersWithCSVs_Works(string invalidKey, string value, string[] expected)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute0.Hosts", "example0.com" },
|
||||
{ "YARP.Routes.MyRoute0.Metadata.Foo", "bar" },
|
||||
{ "YARP.Routes.MyRoute0.MatchHeaders.[0].Name", "x-test-header" },
|
||||
{ "YARP.Routes.MyRoute0.MatchHeaders.[0].Mode", "ExactHeader" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute0.Hosts", "example0.com" },
|
||||
{ "YARP.Routes.MyRoute0.Metadata.Foo", "bar" },
|
||||
{ "YARP.Routes.MyRoute0.MatchHeaders.[0].Name", "x-test-header" },
|
||||
{ "YARP.Routes.MyRoute0.MatchHeaders.[0].Mode", "ExactHeader" },
|
||||
};
|
||||
labels[invalidKey] = value;
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = $"MyCoolClusterId:MyRoute0",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = $"MyCoolClusterId:MyRoute0",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example0.com" },
|
||||
Headers = new List<RouteHeader>() {
|
||||
new RouteHeader(){Name = "x-test-header", Mode = HeaderMatchMode.ExactHeader, Values = expected},
|
||||
}
|
||||
},
|
||||
Metadata = new Dictionary<string, string>(){
|
||||
{ "Foo", "bar"}
|
||||
},
|
||||
ClusterId = "MyCoolClusterId",
|
||||
}
|
||||
};
|
||||
Hosts = new[] { "example0.com" },
|
||||
Headers = new List<RouteHeader>() {
|
||||
new RouteHeader(){Name = "x-test-header", Mode = HeaderMatchMode.ExactHeader, Values = expected},
|
||||
}
|
||||
},
|
||||
Metadata = new Dictionary<string, string>(){
|
||||
{ "Foo", "bar"}
|
||||
},
|
||||
ClusterId = "MyCoolClusterId",
|
||||
}
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -663,33 +663,33 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_InvalidLabelKeys_IgnoresAndDoesNotThrow(string invalidKey, string value)
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Order", "2" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
};
|
||||
labels[invalidKey] = value;
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "Foo", "Bar" },
|
||||
},
|
||||
Hosts = new[] { "example.com" },
|
||||
},
|
||||
};
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>
|
||||
{
|
||||
{ "Foo", "Bar" },
|
||||
},
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
|
||||
|
@ -697,57 +697,57 @@ public class LabelsParserTests
|
|||
public void BuildRoutes_MultipleRoutes_Works()
|
||||
{
|
||||
var labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Path", "v2/{**rest}" },
|
||||
{ "YARP.Routes.MyRoute.Order", "1" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
{ "YARP.Routes.CoolRoute.Hosts", "example.net" },
|
||||
{ "YARP.Routes.CoolRoute.Order", "2" },
|
||||
{ "YARP.Routes.EvenCoolerRoute.Hosts", "example.org" },
|
||||
{ "YARP.Routes.EvenCoolerRoute.Order", "3" },
|
||||
};
|
||||
{
|
||||
{ "YARP.Backend.BackendId", "MyCoolClusterId" },
|
||||
{ "YARP.Routes.MyRoute.Hosts", "example.com" },
|
||||
{ "YARP.Routes.MyRoute.Path", "v2/{**rest}" },
|
||||
{ "YARP.Routes.MyRoute.Order", "1" },
|
||||
{ "YARP.Routes.MyRoute.Metadata.Foo", "Bar" },
|
||||
{ "YARP.Routes.CoolRoute.Hosts", "example.net" },
|
||||
{ "YARP.Routes.CoolRoute.Order", "2" },
|
||||
{ "YARP.Routes.EvenCoolerRoute.Hosts", "example.org" },
|
||||
{ "YARP.Routes.EvenCoolerRoute.Order", "3" },
|
||||
};
|
||||
|
||||
var routes = LabelsParser.BuildRoutes(_testServiceName, labels);
|
||||
|
||||
var expectedRoutes = new List<RouteConfig>
|
||||
{
|
||||
new RouteConfig
|
||||
{
|
||||
new RouteConfig
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "MyCoolClusterId:MyRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example.com" },
|
||||
Path = "v2/{**rest}",
|
||||
},
|
||||
Order = 1,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string> { { "Foo", "Bar" } },
|
||||
Hosts = new[] { "example.com" },
|
||||
Path = "v2/{**rest}",
|
||||
},
|
||||
new RouteConfig
|
||||
Order = 1,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string> { { "Foo", "Bar" } },
|
||||
},
|
||||
new RouteConfig
|
||||
{
|
||||
RouteId = "MyCoolClusterId:CoolRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "MyCoolClusterId:CoolRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example.net" },
|
||||
},
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
Hosts = new[] { "example.net" },
|
||||
},
|
||||
new RouteConfig
|
||||
Order = 2,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
},
|
||||
new RouteConfig
|
||||
{
|
||||
RouteId = "MyCoolClusterId:EvenCoolerRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "MyCoolClusterId:EvenCoolerRoute",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Hosts = new[] { "example.org" },
|
||||
},
|
||||
Order = 3,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
Hosts = new[] { "example.org" },
|
||||
},
|
||||
};
|
||||
Order = 3,
|
||||
ClusterId = "MyCoolClusterId",
|
||||
Metadata = new Dictionary<string, string>(),
|
||||
},
|
||||
};
|
||||
routes.Should().BeEquivalentTo(expectedRoutes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,28 +27,28 @@ public class Startup
|
|||
services.AddControllers();
|
||||
var routes = new[]
|
||||
{
|
||||
new RouteConfig()
|
||||
new RouteConfig()
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
RouteId = "route1",
|
||||
ClusterId = "cluster1",
|
||||
Match = new RouteMatch
|
||||
{
|
||||
Path = "{**catch-all}"
|
||||
}
|
||||
Path = "{**catch-all}"
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
var clusters = new[]
|
||||
{
|
||||
new ClusterConfig()
|
||||
new ClusterConfig()
|
||||
{
|
||||
ClusterId = "cluster1",
|
||||
SessionAffinity = new SessionAffinityConfig { Enabled = true, Policy = "Cookie", AffinityKeyName = ".Yarp.ReverseProxy.Affinity" },
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
ClusterId = "cluster1",
|
||||
SessionAffinity = new SessionAffinityConfig { Enabled = true, Policy = "Cookie", AffinityKeyName = ".Yarp.ReverseProxy.Affinity" },
|
||||
Destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "destination1", new DestinationConfig() { Address = "https://localhost:10000" } }
|
||||
}
|
||||
{ "destination1", new DestinationConfig() { Address = "https://localhost:10000" } }
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
services.AddReverseProxy()
|
||||
.LoadFromMemory(routes, clusters)
|
||||
|
@ -60,18 +60,18 @@ public class Startup
|
|||
.AddTransforms<MyTransformProvider>()
|
||||
.AddTransforms(transformBuilderContext =>
|
||||
{
|
||||
// For each route+cluster pair decide if we want to add transforms, and if so, which?
|
||||
// This logic is re-run each time a route is rebuilt.
|
||||
// For each route+cluster pair decide if we want to add transforms, and if so, which?
|
||||
// This logic is re-run each time a route is rebuilt.
|
||||
|
||||
transformBuilderContext.AddPathPrefix("/prefix");
|
||||
transformBuilderContext.AddPathPrefix("/prefix");
|
||||
|
||||
// Only do this for routes that require auth.
|
||||
if (string.Equals("token", transformBuilderContext.Route.AuthorizationPolicy))
|
||||
// Only do this for routes that require auth.
|
||||
if (string.Equals("token", transformBuilderContext.Route.AuthorizationPolicy))
|
||||
{
|
||||
transformBuilderContext.AddRequestTransform(async transformContext =>
|
||||
{
|
||||
// AuthN and AuthZ will have already been completed after request routing.
|
||||
var ticket = await transformContext.HttpContext.AuthenticateAsync("token");
|
||||
// AuthN and AuthZ will have already been completed after request routing.
|
||||
var ticket = await transformContext.HttpContext.AuthenticateAsync("token");
|
||||
var tokenService = transformContext.HttpContext.RequestServices.GetRequiredService<TokenService>();
|
||||
var token = await tokenService.GetAuthTokenAsync(ticket.Principal);
|
||||
transformContext.ProxyRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
|
@ -80,9 +80,9 @@ public class Startup
|
|||
|
||||
transformBuilderContext.AddResponseTransform(context =>
|
||||
{
|
||||
// Suppress the response body from errors.
|
||||
// The status code was already copied.
|
||||
if (context.ProxyResponse?.IsSuccessStatusCode == false)
|
||||
// Suppress the response body from errors.
|
||||
// The status code was already copied.
|
||||
if (context.ProxyResponse?.IsSuccessStatusCode == false)
|
||||
{
|
||||
context.SuppressResponseBody = true;
|
||||
}
|
||||
|
@ -109,16 +109,16 @@ public class Startup
|
|||
endpoints.MapControllers();
|
||||
endpoints.MapReverseProxy(proxyPipeline =>
|
||||
{
|
||||
// Custom endpoint selection
|
||||
proxyPipeline.Use((context, next) =>
|
||||
// Custom endpoint selection
|
||||
proxyPipeline.Use((context, next) =>
|
||||
{
|
||||
var someCriteria = false; // MeetsCriteria(context);
|
||||
if (someCriteria)
|
||||
if (someCriteria)
|
||||
{
|
||||
var availableDestinationsFeature = context.Features.Get<IReverseProxyFeature>();
|
||||
var destination = availableDestinationsFeature.AvailableDestinations[0]; // PickDestination(availableDestinationsFeature.Destinations);
|
||||
// Load balancing will no-op if we've already reduced the list of available destinations to 1.
|
||||
availableDestinationsFeature.AvailableDestinations = destination;
|
||||
// Load balancing will no-op if we've already reduced the list of available destinations to 1.
|
||||
availableDestinationsFeature.AvailableDestinations = destination;
|
||||
}
|
||||
|
||||
return next();
|
||||
|
|
|
@ -46,16 +46,16 @@ public class Startup
|
|||
endpoints.MapControllers();
|
||||
endpoints.MapReverseProxy(proxyPipeline =>
|
||||
{
|
||||
// Custom endpoint selection
|
||||
proxyPipeline.Use((context, next) =>
|
||||
// Custom endpoint selection
|
||||
proxyPipeline.Use((context, next) =>
|
||||
{
|
||||
var someCriteria = false; // MeetsCriteria(context);
|
||||
if (someCriteria)
|
||||
if (someCriteria)
|
||||
{
|
||||
var availableDestinationsFeature = context.Features.Get<IReverseProxyFeature>();
|
||||
var destination = availableDestinationsFeature.AvailableDestinations[0]; // PickDestination(availableDestinationsFeature.Destinations);
|
||||
// Load balancing will no-op if we've already reduced the list of available destinations to 1.
|
||||
availableDestinationsFeature.AvailableDestinations = destination;
|
||||
// Load balancing will no-op if we've already reduced the list of available destinations to 1.
|
||||
availableDestinationsFeature.AvailableDestinations = destination;
|
||||
}
|
||||
|
||||
return next();
|
||||
|
|
|
@ -31,14 +31,14 @@ internal class Program
|
|||
}
|
||||
|
||||
var scenarioFactories = new Dictionary<string, Func<IScenario>>(StringComparer.OrdinalIgnoreCase) {
|
||||
{"Http1", () => new Http1Scenario()},
|
||||
{"Http2", () => new Http2Scenario()},
|
||||
{"Http2PostExpectContinue", () => new Http2PostExpectContinueScenario()},
|
||||
// Disabled due to a conflict with a workaround to the issue https://github.com/microsoft/reverse-proxy/issues/255.
|
||||
//{"RawUpgrade", () => new RawUpgradeScenario()},
|
||||
{"WebSockets", () => new WebSocketsScenario()},
|
||||
{"SessionAffinity", () => new SessionAffinityScenario()}
|
||||
};
|
||||
{"Http1", () => new Http1Scenario()},
|
||||
{"Http2", () => new Http2Scenario()},
|
||||
{"Http2PostExpectContinue", () => new Http2PostExpectContinueScenario()},
|
||||
// Disabled due to a conflict with a workaround to the issue https://github.com/microsoft/reverse-proxy/issues/255.
|
||||
//{"RawUpgrade", () => new RawUpgradeScenario()},
|
||||
{"WebSockets", () => new WebSocketsScenario()},
|
||||
{"SessionAffinity", () => new SessionAffinityScenario()}
|
||||
};
|
||||
|
||||
if (string.IsNullOrEmpty(parsedArgs.Scenario))
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче