/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Servers/HttpSys/test/FunctionalTests/DelegateTests.cs
375 строк
15 KB
Korolev Dmitry
upgrade cswin32 + fix build (#65516)
24 фев 2026, 03:59
Не верифицирован
24 фев 2026, 03:59
db50e77
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Http; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.InternalTesting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.Security; namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests; public class DelegateTests : LoggedTest { private static readonly string _expectedResponseString = "Hello from delegatee"; [ConditionalFact] [DelegateSupportedCondition(true)] public void IServerDelegationFeature_IsAvailableFromServices() { var builder = new HostBuilder(); builder.ConfigureWebHost(webHost => { webHost.UseHttpSys(); }); using var host = builder.Build(); var server = host.Services.GetRequiredService<IServer>(); var delegationFeature = host.Services.GetRequiredService<IServerDelegationFeature>(); Assert.Same(server, delegationFeature); } [ConditionalFact] [DelegateSupportedCondition(true)] public async Task DelegateRequestTest() { var queueName = Guid.NewGuid().ToString(); using var receiver = Utilities.CreateHttpServer(out var receiverAddress, async httpContext => { await httpContext.Response.WriteAsync(_expectedResponseString); }, options => { options.RequestQueueName = queueName; }, LoggerFactory); DelegationRule destination = default; using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, httpContext => { var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); delegateFeature.DelegateRequest(destination); return Task.CompletedTask; }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); var responseString = await SendRequestAsync(delegatorAddress); Assert.Equal(_expectedResponseString, responseString); destination?.Dispose(); } [ConditionalFact] [DelegateSupportedCondition(true)] public async Task DelegateAfterWriteToResponseBodyShouldThrowTest() { var queueName = Guid.NewGuid().ToString(); using var receiver = Utilities.CreateHttpServer(out var receiverAddress, httpContext => { httpContext.Response.StatusCode = StatusCodes.Status418ImATeapot; return Task.CompletedTask; }, options => { options.RequestQueueName = queueName; }, LoggerFactory); DelegationRule destination = default; using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, async httpContext => { await httpContext.Response.WriteAsync(_expectedResponseString); var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); Assert.False(delegateFeature.CanDelegate); Assert.Throws<InvalidOperationException>(() => delegateFeature.DelegateRequest(destination)); }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); var responseString = await SendRequestAsync(delegatorAddress); Assert.Equal(_expectedResponseString, responseString); destination?.Dispose(); } [ConditionalFact] [DelegateSupportedCondition(true)] public async Task WriteToBodyAfterDelegateShouldNoOp() { var queueName = Guid.NewGuid().ToString(); using var receiver = Utilities.CreateHttpServer(out var receiverAddress, async httpContext => { await httpContext.Response.WriteAsync(_expectedResponseString); }, options => { options.RequestQueueName = queueName; }, LoggerFactory); DelegationRule destination = default; using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, httpContext => { var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); delegateFeature.DelegateRequest(destination); Assert.False(delegateFeature.CanDelegate); httpContext.Response.WriteAsync(_expectedResponseString); return Task.CompletedTask; }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); var responseString = await SendRequestAsync(delegatorAddress); Assert.Equal(_expectedResponseString, responseString); destination?.Dispose(); } [ConditionalFact] [DelegateSupportedCondition(true)] public async Task DelegateAfterRequestBodyReadShouldThrow() { var queueName = Guid.NewGuid().ToString(); using var receiver = Utilities.CreateHttpServer(out var receiverAddress, httpContext => { httpContext.Response.StatusCode = StatusCodes.Status418ImATeapot; return Task.CompletedTask; }, options => { options.RequestQueueName = queueName; }, LoggerFactory); DelegationRule destination = default; using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, async httpContext => { var memoryStream = new MemoryStream(); await httpContext.Request.Body.CopyToAsync(memoryStream); var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); Assert.Throws<InvalidOperationException>(() => delegateFeature.DelegateRequest(destination)); }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); _ = await SendRequestWithBodyAsync(delegatorAddress); destination?.Dispose(); } [ConditionalFact] [DelegateSupportedCondition(false)] public async Task DelegationFeaturesAreNull() { // Testing the DelegateSupportedCondition Assert.True(Environment.OSVersion.Version < new Version(10, 0, 22000), "This should be supported on Win 11."); using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, httpContext => { var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); Assert.Null(delegateFeature); return Task.CompletedTask; }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); Assert.Null(delegationProperty); _ = 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; }, LoggerFactory); DelegationRule destination = default; using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, httpContext => { var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); delegateFeature.DelegateRequest(destination); return Task.CompletedTask; }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); // Send a request to ensure the rule is fully active var responseString = await SendRequestAsync(delegatorAddress); destination?.Dispose(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); responseString = await SendRequestAsync(delegatorAddress); Assert.Equal(_expectedResponseString, responseString); destination?.Dispose(); } [ConditionalFact] [DelegateSupportedCondition(true)] [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/60141")] public async Task DelegateAfterReceiverRestart() { var queueName = Guid.NewGuid().ToString(); using var receiver = Utilities.CreateHttpServer(out var receiverAddress, async httpContext => { await httpContext.Response.WriteAsync(_expectedResponseString); }, options => { options.RequestQueueName = queueName; }, LoggerFactory); DelegationRule destination = default; using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, httpContext => { var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); delegateFeature.DelegateRequest(destination); return Task.CompletedTask; }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); var responseString = await SendRequestAsync(delegatorAddress); Assert.Equal(_expectedResponseString, responseString); // Stop the receiver receiver?.Dispose(); // Start the receiver again but this time we need to use CreateOrAttach to attach to the existing queue and setup the UrlPrefixes using var receiverRestarted = (MessagePump)Utilities.CreateHttpServer(out receiverAddress, async httpContext => { await httpContext.Response.WriteAsync(_expectedResponseString); }, options => { options.RequestQueueName = queueName; options.RequestQueueMode = RequestQueueMode.CreateOrAttach; options.UrlPrefixes.Clear(); options.UrlPrefixes.Add(receiverAddress); }, LoggerFactory); responseString = await SendRequestAsync(delegatorAddress); Assert.Equal(_expectedResponseString, responseString); destination?.Dispose(); } [ConditionalFact] [DelegateSupportedCondition(true)] public async Task DelegateRequestTestCanSetSecurityDescriptor() { // Create a new security descriptor CommonSecurityDescriptor securityDescriptor = new CommonSecurityDescriptor(false, false, string.Empty); // Create a discretionary access control list (DACL) DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, 2); dacl.AddAccess(AccessControlType.Allow, new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), -1, InheritanceFlags.None, PropagationFlags.None); dacl.AddAccess(AccessControlType.Deny, new SecurityIdentifier(WellKnownSidType.BuiltinGuestsSid, null), -1, InheritanceFlags.None, PropagationFlags.None); // Assign the DACL to the security descriptor securityDescriptor.DiscretionaryAcl = dacl; var queueName = Guid.NewGuid().ToString(); using var receiver = Utilities.CreateHttpServer(out var receiverAddress, async httpContext => { await httpContext.Response.WriteAsync(_expectedResponseString); }, options => { options.RequestQueueName = queueName; options.RequestQueueSecurityDescriptor = securityDescriptor; }, LoggerFactory); DelegationRule destination = default; using var delegator = Utilities.CreateHttpServer(out var delegatorAddress, httpContext => { var delegateFeature = httpContext.Features.Get<IHttpSysRequestDelegationFeature>(); delegateFeature.DelegateRequest(destination); return Task.CompletedTask; }, LoggerFactory); var delegationProperty = delegator.Features.Get<IServerDelegationFeature>(); destination = delegationProperty.CreateDelegationRule(queueName, receiverAddress); AssertPermissions(destination.Queue.Handle); unsafe void AssertPermissions(SafeHandle handle) { WIN32_ERROR result = PInvoke.GetSecurityInfo( handle, Windows.Win32.Security.Authorization.SE_OBJECT_TYPE.SE_KERNEL_OBJECT, OBJECT_SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out _, out _, out _, out _, out var pSecurityDescriptor); Assert.Equal(WIN32_ERROR.ERROR_SUCCESS, result); var length = (int)PInvoke.GetSecurityDescriptorLength(pSecurityDescriptor); // Copy the security descriptor to a managed byte array byte[] securityDescriptorBytes = new byte[length]; Marshal.Copy(new IntPtr(pSecurityDescriptor.Value), securityDescriptorBytes, 0, length); // Convert the byte array to a RawSecurityDescriptor var securityDescriptor = new RawSecurityDescriptor(securityDescriptorBytes, 0); var checkedAllowUser = false; var checkedDenyGuest = false; foreach (CommonAce ace in securityDescriptor.DiscretionaryAcl) { if (ace.SecurityIdentifier.IsWellKnown(WellKnownSidType.BuiltinGuestsSid)) { Assert.Equal(AceType.AccessDenied, ace.AceType); checkedDenyGuest = true; } else if (ace.SecurityIdentifier.IsWellKnown(WellKnownSidType.BuiltinUsersSid)) { Assert.Equal(AceType.AccessAllowed, ace.AceType); checkedAllowUser = true; } } PInvoke.LocalFree((HLOCAL)pSecurityDescriptor.Value); Assert.True(checkedDenyGuest && checkedAllowUser, "DACL does not contain the expected ACEs"); } var responseString = await SendRequestAsync(delegatorAddress); Assert.Equal(_expectedResponseString, responseString); destination?.Dispose(); } private async Task<string> SendRequestAsync(string uri) { using var client = new HttpClient(); return await client.GetStringAsync(uri); } private async Task<string> SendRequestWithBodyAsync(string uri) { using var client = new HttpClient(); var content = new StringContent("Sample request body"); var response = await client.PostAsync(uri, content); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } }