Следующий пример Program.Main демонстрирует использование chmod через P / Invoke. Это решение позволяет использовать управляемые сокеты на Windows и переключается на libuv, когда ListenUnixSocket
настроен через настройки приложений. json, и в этом случае вызывает chmod
непосредственно при запуске, чтобы установить sh разрешения на сокеты.
Код для класса Chmod
в значительной степени снят с: https://silvercircle.github.io/2018/08/26/serving-net-core-kestrel-linux-unix-sockets/
UseLibuv
требует зависимости от Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv
через NuGet.
namespace UnixSocketDemo
{
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using static System.String;
public class Program
{
private static string _unixSocket = null;
public static async Task Main(string[] args)
{
var webHost = BuildWebHost(args);
await webHost.StartAsync();
if (!IsNullOrWhiteSpace(_unixSocket))
Chmod.Set(_unixSocket);
await webHost.WaitForShutdownAsync();
}
public static IWebHost BuildWebHost(string[] args)
{
var builder = WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) => config.SetBasePath(Directory.GetCurrentDirectory()))
.UseStartup<Startup>();
var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
var kestrelConfig = config.GetSection("Kestrel");
if (kestrelConfig.Exists())
{
_unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
if (!IsNullOrWhiteSpace(_unixSocket))
builder.UseLibuv();
builder.ConfigureKestrel((hostingContext, serverOptions) =>
{
serverOptions.Configure(kestrelConfig);
if (!IsNullOrWhiteSpace(_unixSocket))
serverOptions.ListenUnixSocket(_unixSocket);
});
}
return builder.Build();
}
private static class Chmod
{
[DllImport("libc", EntryPoint="chmod", SetLastError = true)]
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "interop")]
private static extern int chmod(string pathname, int mode);
// user permissions
const int S_IRUSR = 0x100;
const int S_IWUSR = 0x80;
const int S_IXUSR = 0x40;
// group permission
const int S_IRGRP = 0x20;
const int S_IWGRP = 0x10;
const int S_IXGRP = 0x8;
// other permissions
const int S_IROTH = 0x4;
const int S_IWOTH = 0x2;
const int S_IXOTH = 0x1;
public static void Set(string filename)
{
const int _0755 =
S_IRUSR | S_IXUSR | S_IWUSR
| S_IRGRP | S_IXGRP | S_IWGRP
| S_IROTH | S_IXOTH | S_IWOTH;
if (0 != chmod(Path.GetFullPath(filename), (int)_0755))
throw new Exception("Could not set Unix socket permissions");
}
}
}
}