# ファイルサーバー

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

Sisk は `Sisk.Http.FileSystem` 名前空間を提供し、静的ファイルの配信、ディレクトリ一覧、ファイル変換のためのツールが含まれています。この機能により、ローカルディレクトリからファイルを配信でき、Range リクエスト（音声/動画ストリーミング）やカスタムファイル処理もサポートします。

## 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/ja/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

| プロパティ | 説明 |
|---|---|
| `RootDirectoryPath` | ファイルが提供されるルートディレクトリへの絶対パスまたは相対パス。 |
| `RoutePrefix` | ファイル解決時にリクエストパスから除去されるルートプレフィックス。デフォルトは `/`。 |
| `AllowDirectoryListing` | `true` に設定すると、ディレクトリが要求され、インデックスファイルが見つからない場合にディレクトリ一覧を有効にします。デフォルトは `false`。 |
| `FileConverters` | 提供前にファイルを変換するために使用される `HttpFileServerFileConverter` のリスト。 |

## Directory Listing

`AllowDirectoryListing` が有効で、ユーザーがディレクトリパスを要求した場合、Sisk はそのディレクトリの内容を一覧表示する HTML ページを生成します。

ディレクトリ一覧には以下が含まれます：
- 親ディレクトリへのナビゲーション (`..`)。
- サブディレクトリの一覧。
- サイズと最終更新日を含むファイルの一覧。

## File Converters

ファイルコンバータを使用すると、特定のファイルタイプをインターセプトして別の方法で処理できます。たとえば、画像をトランスコードしたり、ファイルをオンザフライで圧縮したり、部分コンテンツ（Range リクエスト）でファイルを配信したりできます。

Sisk にはメディアストリーミング用の組み込みコンバータが 2 つ含まれています：
- `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());
```
