# Servidor de Arquivos

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

Sisk fornece o namespace `Sisk.Http.FileSystem`, que contém ferramentas para servir arquivos estáticos, listagem de diretórios e conversão de arquivos. Esse recurso permite servir arquivos a partir de um diretório local, com suporte a solicitações de intervalo (streaming de áudio/vídeo) e processamento personalizado de arquivos.

## Servindo arquivos estáticos

A maneira mais simples de servir arquivos estáticos é [Router.MapFileSystem](https://docs.sisk-framework.org/api/Sisk.Core.Routing.Router.MapFileSystem.md). Esse método mapeia um prefixo de URL para um diretório no disco.

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

// mapeia a raiz do servidor para o diretório atual
mainRouter.MapFileSystem("/", Directory.GetCurrentDirectory());

// mapeia /assets para a pasta "public/assets"
mainRouter.MapFileSystem(
    "/assets",
    Path.Combine(Directory.GetCurrentDirectory(), "public", "assets"));
```

Quando uma requisição corresponde ao prefixo da rota, o `HttpFileServerHandler` procurará um arquivo no diretório especificado. Se encontrado, ele servirá o arquivo; caso contrário, retornará uma resposta 404 (ou 403 se o acesso for negado).

`HttpFileServer.CreateServingRoute` ainda está disponível quando você precisa criar um objeto `Route` explicitamente, mas `MapFileSystem` é a opção mais direta para o código da aplicação.

Ambos os métodos criam um [PrefixRoute](https://docs.sisk-framework.org/api/Sisk.Core.Routing.PrefixRoute.md) (uma rota regex antes do Sisk 1.7), que é uma [rota dinâmica](https://docs.sisk-framework.org/pt-br/docs/fundamentals/routing.md#matching-precedence). Rotas estáticas são sempre testadas antes dele, portanto um servidor de arquivos mapeado para `/` funciona como fallback para os caminhos que suas outras rotas não tratam. As rotas do servidor de arquivos não são afetadas por [HttpServerConfiguration.ForceTrailingSlash](https://docs.sisk-framework.org/api/Sisk.Core.Http.HttpServerConfiguration.ForceTrailingSlash.md).

## HttpFileServerHandler

Para ter mais controle sobre como os arquivos são servidos, você pode instanciar e configurar o `HttpFileServerHandler` manualmente.

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

// habilita a listagem de diretórios (desabilitada por padrão)
fileHandler.AllowDirectoryListing = true;

// define um prefixo de rota personalizado (isso será removido do caminho da requisição)
fileHandler.RoutePrefix = "/public";

// registra o handler em /public
mainRouter.MapFileSystem("/public", fileHandler);
```

### Configuração

| Propriedade | Descrição |
|---|---|
| `RootDirectoryPath` | O caminho absoluto ou relativo para o diretório raiz a partir do qual os arquivos são servidos. |
| `RoutePrefix` | O prefixo de rota que será removido do caminho da requisição ao resolver arquivos. O padrão é `/`. |
| `AllowDirectoryListing` | Se definido como `true`, habilita a listagem de diretórios quando um diretório é solicitado e nenhum arquivo índice é encontrado. O padrão é `false`. |
| `FileConverters` | Uma lista de `HttpFileServerFileConverter` usada para transformar arquivos antes de servi-los. |

## Listagem de Diretório

Quando `AllowDirectoryListing` está habilitado e o usuário solicita um caminho de diretório, o Sisk gerará uma página HTML listando o conteúdo desse diretório.

A listagem de diretório inclui:
- Navegação para o diretório pai (`..`).
- Lista de subdiretórios.
- Lista de arquivos com tamanho e data da última modificação.

## Conversores de Arquivo

Conversores de arquivo permitem interceptar tipos de arquivo específicos e tratá-los de forma diferente. Por exemplo, você pode querer transcodificar uma imagem, comprimir um arquivo em tempo real ou servir um arquivo usando conteúdo parcial (solicitações de intervalo).

O Sisk inclui dois conversores embutidos para streaming de mídia:
- `HttpFileAudioConverter`: Lida com `.mp3`, `.ogg`, `.wav`, `.flac`, `.ogv`.
- `HttpFileVideoConverter`: Lida com `.webm`, `.avi`, `.mkv`, `.mpg`, `.mpeg`, `.wmv`, `.mov`, `.mp4`.

Esses conversores habilitam o suporte a **HTTP Range Requests**, permitindo que os clientes avancem em arquivos de áudio e vídeo.

### Criando um conversor personalizado

Para criar um conversor de arquivo personalizado, herde de `HttpFileServerFileConverter` e implemente `CanConvert` e `Convert`.

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

public class MyTextConverter : HttpFileServerFileConverter
{
    public override bool CanConvert(FileInfo file)
    {
        // aplicar apenas a arquivos .txt
        return file.Extension.Equals(".txt", StringComparison.OrdinalIgnoreCase);
    }

    public override HttpResponse Convert(FileInfo file, HttpRequest request)
    {
        string content = File.ReadAllText(file.FullName);
        
        // converter todo o conteúdo de texto para maiúsculas
        return new HttpResponse(200)
        {
            Content = new StringContent(content.ToUpper())
        };
    }
}
```

Em seguida, adicione-o ao seu handler:

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