Skip to content

HttpSysRequestDelegationFeature - DelegationRule.Dipose() doesn't clean up delegation flag with http.sys #27126

Closed
@NGloreous

Description

@NGloreous

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/

Metadata

Metadata

Assignees

Labels

affected-very-fewThis issue impacts very few customersarea-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsbugThis issue describes a behavior which is not expected - a bug.severity-minorThis label is used by an internal tool

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions