# Поставщик конфигурации INI

Source: https://docs.sisk-framework.org/ru/docs/extensions/ini-configuration.html

Sisk имеет способ получения стартовых конфигураций, отличных от JSON. На самом деле любой конвейер, реализующий [IConfigurationReader](https://docs.sisk-framework.org/api/Sisk.Core.Http.Hosting.IConfigurationReader.md), можно использовать с [PortableConfigurationBuilder.WithConfigurationPipeline](https://docs.sisk-framework.org/api/Sisk.Core.Http.Hosting.PortableConfigurationBuilder.md), читая конфигурацию сервера из любого типа файлов.

Пакет [Sisk.IniConfiguration](https://www.nuget.org/packages/Sisk.IniConfiguration/) предоставляет потоковый читатель INI‑файлов, который не бросает исключения при типичных синтаксических ошибках и имеет простой синтаксис конфигурации. Этот пакет можно использовать вне фреймворка Sisk, что даёт гибкость проектам, которым нужен эффективный читатель INI‑документов.

## Установка

Чтобы установить пакет, вы можете начать с:

```bash
$ dotnet add package Sisk.IniConfiguration
```

Вы также можете установить основной пакет, который не включает INI‑[IConfigurationReader](https://docs.sisk-framework.org/api/Sisk.Core.Http.Hosting.IConfigurationReader), не зависит от Sisk, а содержит только сериализаторы INI:

```bash
$ dotnet add package Sisk.IniConfiguration.Core
```

С основным пакетом вы можете использовать его в коде, как показано в примере ниже:

```cs
class Program
{
    static HttpServerHostContext Host = null!;

    static void Main(string[] args)
    {
        Host = HttpServer.CreateBuilder()
            .UsePortableConfiguration(config =>
            {
                config.WithConfigFile("app.ini", createIfDontExists: true);
                
                // использует конфигурационный читатель IniConfigurationReader
                config.WithConfigurationPipeline<IniConfigurationReader>();
            })
            .UseRouter(r =>
            {
                r.MapGet("/", SayHello);
            })
            .Build();
        
        Host.Start();
    }

    static HttpResponse SayHello(HttpRequest request)
    {
        string? name = Host.Parameters["name"] ?? "world";
        return new HttpResponse($"Hello, {name}!");
    }
}
```

Код выше будет искать файл `app.ini` в текущем каталоге процесса (`CurrentDirectory`). Файл INI выглядит так:

```ini
[Server]
# Multiple listen addresses are supported
Listen = http://localhost:5552/
Listen = http://localhost:5553/
ThrowExceptions = false
AccessLogsStream = console

[Cors]
AllowMethods = GET, POST
AllowHeaders = Content-Type, Authorization
AllowOrigin = *

[Parameters]
Name = "Kanye West"
```

## Синтаксис и особенности INI

Текущий вариант реализации:

- Имена свойств и секций **не чувствительны к регистру**.
- Имена свойств и их значения **обрезаются**, если только значения не заключены в кавычки.
- Значения могут быть заключены в одинарные или двойные кавычки. Внутри кавычек могут быть переносы строк.
- Комментарии поддерживаются с помощью `#` и `;`. Кроме того, **допускаются конечные (trailing) комментарии**.
- Свойства могут иметь несколько значений.

Подробную документацию о «вкусе» INI‑парсера, используемого в Sisk, можно найти в [этом документе](https://github.com/sisk-http/archive/blob/master/ext/ini-reader-syntax.md).

Используя следующий код ini в качестве примера:

```ini
One = 1
Value = this is an value
Another value = "this value
    has an line break on it"

; the code below has some colors
[some section]
Color = Red
Color = Blue
Color = Yellow ; do not use yellow
```

Разберите его с помощью:

```csharp
// разбирает ini‑текст из строки
IniDocument doc = IniDocument.FromString(iniText);

// получить одно значение
string? one = doc.Global.GetOne("one");
string? anotherValue = doc.Global.GetOne("another value");

// получить несколько значений
string[]? colors = doc.GetSection("some section")?.GetMany("color");
```

## Параметры конфигурации

| Раздел и имя | Разрешено несколько значений | Описание |
| ------------ | --------------------------- | -------- |
| `Server.Listen` | Yes | Адреса/порты, на которых сервер слушает. |
| `Server.Encoding` | No | Кодировка по умолчанию сервера. |
| `Server.MaximumContentLength` | No | Максимальный размер `content-length` сервера в байтах. Если не указано, используется значение по умолчанию сервера (100 МБ начиная с Sisk 1.7). Используйте `0` для отсутствия ограничения. |
| `Server.IncludeRequestIdHeader` | No | Указывает, должен ли HTTP‑сервер отправлять заголовок `X-Request-Id`. |
| `Server.ThrowExceptions` | No | Указывает, должны ли необработанные исключения выбрасываться. |
| `Server.AccessLogsStream` | No | Указывает поток вывода журнала доступа. |
| `Server.ErrorsLogsStream` | No | Указывает поток вывода журнала ошибок. |
| `Cors.AllowMethods` | No | Указывает значение заголовка CORS `Allow-Methods`. |
| `Cors.AllowHeaders` | No | Указывает значение заголовка CORS `Allow-Headers`. |
| `Cors.AllowOrigins` | No | Указывает несколько заголовков `Allow-Origin`, разделённых запятыми. Подробнее см. [AllowOrigins](https://docs.sisk-framework.org/api/Sisk.Core.Entity.CrossOriginResourceSharingHeaders.AllowOrigins.md). |
| `Cors.AllowOrigin` | No | Указывает один заголовок `Allow-Origin`. |
| `Cors.ExposeHeaders` | No | Указывает значение заголовка CORS `Expose-Headers`. |
| `Cors.AllowCredentials` | No | Указывает значение заголовка CORS `Allow-Credentials`. |
| `Cors.MaxAge` | No | Указывает значение заголовка CORS `Max-Age`. |
