[release/5.0] DelegationRule.Dispose() unsets delegation property on the queue (#28514)
* Unset delegation propery from source queue. This removes the process from the target URL group and allows the delegation rule to be added back later on in the processes lifetime * Add test * Add disposing pattern Co-authored-by: Nolan Glore <nglore@microsoft.com>
This commit is contained in:
parent
8a3c8653cd
commit
e47cbf6de6
|
|
@ -13,6 +13,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
public class DelegationRule : IDisposable
|
public class DelegationRule : IDisposable
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
private readonly UrlGroup _sourceQueueUrlGroup;
|
||||||
|
private bool _disposed;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the Http.Sys request queue
|
/// The name of the Http.Sys request queue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -23,8 +25,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
public string UrlPrefix { get; }
|
public string UrlPrefix { get; }
|
||||||
internal RequestQueue Queue { get; }
|
internal RequestQueue Queue { get; }
|
||||||
|
|
||||||
internal DelegationRule(string queueName, string urlPrefix, ILogger logger)
|
internal DelegationRule(UrlGroup sourceQueueUrlGroup, string queueName, string urlPrefix, ILogger logger)
|
||||||
{
|
{
|
||||||
|
_sourceQueueUrlGroup = sourceQueueUrlGroup;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
QueueName = queueName;
|
QueueName = queueName;
|
||||||
UrlPrefix = urlPrefix;
|
UrlPrefix = urlPrefix;
|
||||||
|
|
@ -34,8 +37,20 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Queue.UrlGroup?.Dispose();
|
if (_disposed)
|
||||||
Queue?.Dispose();
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_disposed = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_sourceQueueUrlGroup.UnSetDelegationProperty(Queue, throwOnError: false);
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException) { /* Server may have been shutdown */ }
|
||||||
|
Queue.UrlGroup.Dispose();
|
||||||
|
Queue.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerDelegationProperty, new IntPtr(&propertyInfo), (uint)RequestPropertyInfoSize);
|
SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerDelegationProperty, new IntPtr(&propertyInfo), (uint)RequestPropertyInfoSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal unsafe void UnSetDelegationProperty(RequestQueue destination, bool throwOnError = true)
|
||||||
|
{
|
||||||
|
var propertyInfo = new HttpApiTypes.HTTP_BINDING_INFO();
|
||||||
|
propertyInfo.Flags = HttpApiTypes.HTTP_FLAGS.NONE;
|
||||||
|
propertyInfo.RequestQueueHandle = destination.Handle.DangerousGetHandle();
|
||||||
|
|
||||||
|
SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY.HttpServerDelegationProperty, new IntPtr(&propertyInfo), (uint)RequestPropertyInfoSize, throwOnError);
|
||||||
|
}
|
||||||
|
|
||||||
internal void SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY property, IntPtr info, uint infosize, bool throwOnError = true)
|
internal void SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY property, IntPtr info, uint infosize, bool throwOnError = true)
|
||||||
{
|
{
|
||||||
Debug.Assert(info != IntPtr.Zero, "SetUrlGroupProperty called with invalid pointer");
|
Debug.Assert(info != IntPtr.Zero, "SetUrlGroupProperty called with invalid pointer");
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
||||||
|
|
||||||
public DelegationRule CreateDelegationRule(string queueName, string uri)
|
public DelegationRule CreateDelegationRule(string queueName, string uri)
|
||||||
{
|
{
|
||||||
var rule = new DelegationRule(queueName, uri, _logger);
|
var rule = new DelegationRule(_queue.UrlGroup, queueName, uri, _logger);
|
||||||
_queue.UrlGroup.SetDelegationProperty(rule.Queue);
|
_queue.UrlGroup.SetDelegationProperty(rule.Queue);
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,38 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
||||||
_ = await SendRequestAsync(delegatorAddress);
|
_ = await SendRequestAsync(delegatorAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[DelegateSupportedCondition(true)]
|
||||||
|
public async Task UpdateDelegationRuleTest()
|
||||||
|
{
|
||||||
|
var queueName = Guid.NewGuid().ToString();
|
||||||
|
using var receiver = Utilities.CreateHttpServer(out var receiverAddress, async httpContext =>
|
||||||
|
{
|
||||||
|
await httpContext.Response.WriteAsync(_expectedResponseString);
|
||||||
|
},
|
||||||
|
options =>
|
||||||
|
{
|
||||||
|
options.RequestQueueName = queueName;
|
||||||
|
});
|
||||||
|
|
||||||
|
DelegationRule destination = default;
|
||||||
|
|
||||||
|
using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, httpContext =>
|
||||||
|
{
|
||||||
|
var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>();
|
||||||
|
delegateFeature.DelegateRequest(destination);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
});
|
||||||
|
|
||||||
|
var delegationProperty = delegator.Features.Get<IServerDelegationFeature>();
|
||||||
|
destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress);
|
||||||
|
destination?.Dispose();
|
||||||
|
destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress);
|
||||||
|
var responseString = await SendRequestAsync(delegatorAddress);
|
||||||
|
Assert.Equal(_expectedResponseString, responseString);
|
||||||
|
destination?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<string> SendRequestAsync(string uri)
|
private async Task<string> SendRequestAsync(string uri)
|
||||||
{
|
{
|
||||||
using var client = new HttpClient();
|
using var client = new HttpClient();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue