Description
Describe the bug
When a new DelegationRule is created, SetDelegationProperty gets called to add a HttpServerDelegationProperty property flag to the RequestQueue owned/created by the process (i.e. not the RequestQueue the delegator is trying to delegate to). When a DelegationRule is disposed, this property flag is not unset. This keeps the delegator process linked to destination queue and prevents a new DelegationRule rule for the same from being created later on.
Ideally as a consumer of this feature I want to be able to dynamically add/remove rules in production via config without the need to restart the process and this bug blocks this ability.
Here is a example fix that I've validated which unsets the property when disposing the delegation rule: master...NGloreous:user/nglore/delegation/unsetdelegation
To Reproduce
namespace Sample
{
public class Startup
{
private DelegationRule _delegationRule;
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime, IWebHostEnvironment env)
{
var delegator = app.ServerFeatures.Get<IServerDelegationFeature>();
app.Run(context =>
{
using (delegationRule = delegator.CreateDelegationRule("DefaultAppPool", "http://*:80/"))
{
var transferFeature = context.Features.Get<IHttpSysRequestTransferFeature>();
transferFeature.TransferRequest(delegationRule);
return Task.CompletedTask;
}
});
}
}
}
Exceptions (if any)
With the above code, the first request received works fine (assuming you have the fix for #26982) but on subsequent request the below exception is throw from the call to CreateDelegationRule.
Microsoft.AspNetCore.Server.HttpSys.HttpSysException (183): Cannot create a file when that file already exists.
at Microsoft.AspNetCore.Server.HttpSys.UrlGroup.SetProperty(HTTP_SERVER_PROPERTY property, IntPtr info, UInt32 infosize, Boolean throwOnError)
at Microsoft.AspNetCore.Server.HttpSys.UrlGroup.SetDelegationProperty(RequestQueue destination)
at Microsoft.AspNetCore.Server.HttpSys.ServerDelegationPropertyFeature.CreateDelegationRule(String queueName, String uri)
Also if you run "netsh http show servicestate" after making the first request you will see that the delegator process is still attached to the queue.
Request queue name: DefaultAppPool
Security descriptor: O:BAG:SYD:AI(A;;FR;;;S-1-5-82-3006700770-424185619-1745488364-794895919-4004696415)(A;;FA;;;SY)(A;;0x12019f;;;BA)
Version: 2.0
State: Active
Request queue 503 verbosity level: Limited
Max requests: 1000
Number of active processes attached: 2
Controller process:
ID: 6436, image: C:\Windows\System32\svchost.exe
Processes:
ID: 4836, image: C:\Windows\System32\inetsrv\w3wp.exe
ID: 2800, image: C:\Users\Administrator\Desktop\delegator\delegator.exe
Registered URLs:
HTTP://*:80/