# Файловый сервер

Source: https://docs.sisk-framework.org/ru/docs/features/file-server.html

Sisk предоставляет пространство имён `Sisk.Http.FileSystem`, которое содержит инструменты для обслуживания статических файлов, отображения содержимого каталогов и конвертации файлов. Эта возможность позволяет обслуживать файлы из локального каталога, поддерживая запросы диапазонов (стриминг аудио/видео) и пользовательскую обработку файлов.

## Serving static files

Самый простой способ обслуживать статические файлы — использовать [Router.MapFileSystem](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.MapFileSystem.md). Этот метод сопоставляет префикс URL с каталогом на диске.

```cs
using Sisk.Core.Http;
using Sisk.Core.Http.FileSystem;

// сопоставляет корень сервера с текущей директорией
mainRouter.MapFileSystem("/", Directory.GetCurrentDirectory());

// сопоставляет /assets с папкой "public/assets"
mainRouter.MapFileSystem(
    "/assets",
    Path.Combine(Directory.GetCurrentDirectory(), "public", "assets"));
```

Когда запрос совпадает с префиксом маршрута, `HttpFileServerHandler` будет искать файл в указанном каталоге. Если файл найден, он будет отдан клиенту; иначе будет возвращён ответ 404 (или 403, если доступ запрещён).

`HttpFileServer.CreateServingRoute` всё ещё доступен, когда необходимо явно создать объект `Route`, но `MapFileSystem` — самый прямой вариант для кода приложения.

Оба метода создают [PrefixRoute](https://docs.sisk-framework.org/api/Sisk.Core.Routing.PrefixRoute.md) (регулярный маршрут до версии Sisk 1.7), который является [dynamic route](https://docs.sisk-framework.org/ru/docs/fundamentals/routing.md#matching-precedence). Статические маршруты всегда проверяются раньше, поэтому файловый сервер, смонтированный на `/`, работает как резервный вариант для путей, которые не обрабатывают другие маршруты. Маршруты файлового сервера не зависят от [HttpServerConfiguration.ForceTrailingSlash](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ForceTrailingSlash.md).

## HttpFileServerHandler

Для более тонкого контроля над тем, как обслуживаются файлы, можно создать и настроить `HttpFileServerHandler` вручную.

```cs
var fileHandler = new HttpFileServerHandler("/var/www/html");

// включить отображение каталога (по умолчанию отключено)
fileHandler.AllowDirectoryListing = true;

// задать пользовательский префикс маршрута (он будет удалён из пути запроса)
fileHandler.RoutePrefix = "/public";

// зарегистрировать обработчик по пути /public
mainRouter.MapFileSystem("/public", fileHandler);
```

### Configuration

| Property | Description |
|---|---|
| `RootDirectoryPath` | Абсолютный или относительный путь к корневому каталогу, из которого обслуживаются файлы. |
| `RoutePrefix` | Префикс маршрута, который будет удалён из пути запроса при разрешении файлов. По умолчанию `/`. |
| `AllowDirectoryListing` | Если `true`, включает отображение содержимого каталога при запросе каталога без файла‑индекса. По умолчанию `false`. |
| `FileConverters` | Список `HttpFileServerFileConverter`, используемых для преобразования файлов перед их отдачей. |

## Directory Listing

Когда включено `AllowDirectoryListing` и пользователь запрашивает путь к каталогу, Sisk генерирует HTML‑страницу со списком содержимого этого каталога.

В отображении каталога присутствует:
- Навигация к родительскому каталогу (`..`).
- Список подкаталогов.
- Список файлов с указанием размера и даты последнего изменения.

## File Converters

Конвертеры файлов позволяют перехватывать определённые типы файлов и обрабатывать их иначе. Например, можно транскодировать изображение, сжимать файл «на лету» или обслуживать файл частично (Range‑запросы).

Sisk включает два встроенных конвертера для потоковой передачи медиа:
- `HttpFileAudioConverter`: Обрабатывает `.mp3`, `.ogg`, `.wav`, `.flac`, `.ogv`.
- `HttpFileVideoConverter`: Обрабатывает `.webm`, `.avi`, `.mkv`, `.mpg`, `.mpeg`, `.wmv`, `.mov`, `.mp4`.

Эти конвертеры обеспечивают поддержку **HTTP Range Requests**, позволяя клиентам перемещаться по аудио‑ и видеофайлам.

### Creating a custom converter

Чтобы создать собственный конвертер файлов, наследуйте `HttpFileServerFileConverter` и реализуйте методы `CanConvert` и `Convert`.

```cs
using Sisk.Core.Http;
using Sisk.Core.Http.FileSystem;

public class MyTextConverter : HttpFileServerFileConverter
{
    public override bool CanConvert(FileInfo file)
    {
        // применять только к файлам .txt
        return file.Extension.Equals(".txt", StringComparison.OrdinalIgnoreCase);
    }

    public override HttpResponse Convert(FileInfo file, HttpRequest request)
    {
        string content = File.ReadAllText(file.FullName);
        
        // преобразовать весь текст в верхний регистр
        return new HttpResponse(200)
        {
            Content = new StringContent(content.ToUpper())
        };
    }
}
```

Затем добавьте его в ваш обработчик:

```cs
var handler = new HttpFileServerHandler("./files");
handler.FileConverters.Add(new MyTextConverter());
```
