Closed
Description
Background and Motivation
Public API for named pipes transport - #44426
The transport is still work-in-progress. This API issue reflects its ideal final API shape, not the PR's current state.
Proposed API
Feature to get the server stream of the name pipe connection. Used to access methods like GetImpersonatedUser
and RunAs
from the pipe. Similar to IConnectionSocketFeature
.
namespace Microsoft.AspNetCore.Connections.Features;
/// <summary>
/// Provides access to the connection's underlying <see cref="NamedPipeServerStream"/>.
/// </summary>
public interface IConnectionNamedPipeFeature
{
/// <summary>
/// Gets the underlying <see cref="NamedPipeServerStream"/>.
/// </summary>
NamedPipeServerStream NamedPipe { get; }
}
Options type for named pipes transport. Similar to SocketTransportOptions
.
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.NamedPipes;
/// <summary>
/// Options for named pipe based transports.
/// </summary>
public sealed class NamedPipeTransportOptions
{
/// <summary>
/// The maximum length of the pending connection queue.
/// </summary>
/// <remarks>
/// Defaults to 512 pending connections.
/// </remarks>
public int Backlog { get; set; } = 512;
/// <summary>
/// Gets or sets the maximum unconsumed incoming bytes the transport will buffer.
/// <para>
/// A value of <see langword="null"/> or 0 disables backpressure entirely allowing unlimited buffering.
/// Unlimited server buffering is a security risk given untrusted clients.
/// </para>
/// </summary>
/// <remarks>
/// Defaults to 1 MiB.
/// </remarks>
public long? MaxReadBufferSize { get; set; } = 1024 * 1024;
/// <summary>
/// Gets or sets the maximum outgoing bytes the transport will buffer before applying write backpressure.
/// <para>
/// A value of <see langword="null"/> or 0 disables backpressure entirely allowing unlimited buffering.
/// Unlimited server buffering is a security risk given untrusted clients.
/// </para>
/// </summary>
/// <remarks>
/// Defaults to 64 KiB.
/// </remarks>
public long? MaxWriteBufferSize { get; set; } = 64 * 1024;
/// <summary>
/// Gets or sets a value that indicates that the pipe can only be connected to by a client created by
/// the same user account.
/// <para>
/// On Windows, a value of true verifies both the user account and elevation level.
/// </para>
/// </summary>
/// <remarks>
/// Defaults to true.
/// </remarks>
public bool CurrentUserOnly { get; set; } = true;
/// <summary>
/// Gets or sets the security information that determines the access control and audit security for pipes.
/// </summary>
public PipeSecurity? PipeSecurity { get; set; }
}
Extension methods to register named pipes services and/or customize options.
namespace Microsoft.AspNetCore.Hosting;
/// <summary>
/// <see cref="IWebHostBuilder" /> extension methods to configure the Named Pipes transport to be used by Kestrel.
/// </summary>
public static class WebHostBuilderNamedPipeExtensions
{
/// <summary>
/// Specify Named Pipes as the transport to be used by Kestrel.
/// </summary>
/// <param name="hostBuilder">
/// The <see cref="IWebHostBuilder" /> to configure.
/// </param>
/// <returns>
/// The <see cref="IWebHostBuilder" />.
/// </returns>
public static IWebHostBuilder UseNamedPipes(this IWebHostBuilder hostBuilder)
{
return hostBuilder.ConfigureServices(services =>
{
services.AddSingleton<IConnectionListenerFactory, NamedPipeTransportFactory>();
});
}
/// <summary>
/// Specify Named Pipes as the transport to be used by Kestrel.
/// </summary>
/// <param name="hostBuilder">
/// The <see cref="IWebHostBuilder" /> to configure.
/// </param>
/// <param name="configureOptions">
/// A callback to configure transport options.
/// </param>
/// <returns>
/// The <see cref="IWebHostBuilder" />.
/// </returns>
public static IWebHostBuilder UseNamedPipes(this IWebHostBuilder hostBuilder, Action<NamedPipeTransportOptions> configureOptions)
{
return hostBuilder.UseNamedPipes().ConfigureServices(services =>
{
services.Configure(configureOptions);
});
}
}
New methods on KestrelServerOptions to register listener. There isn't a public NamedPipeEndPoint
to pass to Listen(EndPoint)
so these methods will be the only way to listen for a named pipe.
namespace Microsoft.AspNetCore.Server.Kestrel.Core;
public class KestrelServerOptions
{
/// <summary>
/// Bind to given named pipe.
/// </summary>
public void ListenNamedPipe(string pipeName);
/// <summary>
/// Bind to given named pipe.
/// Specify callback to configure endpoint-specific settings.
/// </summary>
public void ListenNamedPipe(string pipeName, Action<ListenOptions> configure);
}
Usage Examples
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseNamedPipes(); // note: may be registered by default in .NET 8
builder.WebHost.UseKestrel(o =>
{
o.ListenNamedPipe("MyCoolPipe");
});
var app = builder.Build();
app.MapGet("/", (HttpContext context) =>
{
var pipe = context.Features.Get<IConnectionNamedPipeFeature>().NamedPipe;
return $"Hello {pipe.GetImpersonationUserName()}";
});
app.Run();