[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
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly UrlGroup _sourceQueueUrlGroup;
|
||||
private bool _disposed;
|
||||
/// <summary>
|
||||
/// The name of the Http.Sys request queue
|
||||
/// </summary>
|
||||
|
|
@ -23,8 +25,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
public string UrlPrefix { 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;
|
||||
QueueName = queueName;
|
||||
UrlPrefix = urlPrefix;
|
||||
|
|
@ -34,8 +37,20 @@ namespace Microsoft.AspNetCore.Server.HttpSys
|
|||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Queue.UrlGroup?.Dispose();
|
||||
Queue?.Dispose();
|
||||
if (_disposed)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var rule = new DelegationRule(queueName, uri, _logger);
|
||||
var rule = new DelegationRule(_queue.UrlGroup, queueName, uri, _logger);
|
||||
_queue.UrlGroup.SetDelegationProperty(rule.Queue);
|
||||
return rule;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,6 +161,38 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
_ = 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)
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
|
|
|
|||
Loading…
Reference in New Issue