静的コンテンツの配信

Estimated reading time: 1 minute

Ktorはビルトインで静的コンテンツ配信をサポートしています。 スタイルシートやスクリプトや画像等を配信したいときに便利な機能です:

This feature is defined in the class io.ktor.routing.Routing and no additional artifacts are required.

ファイルとフォルダの指定

static関数を使い、Ktorに特定URIを静的コンテンツのように扱うよう指定し、そのファイルがどこにあるのかも定義することができます。 すべてのコンテンツは現在のworkingディレクトリからの相対パスで扱われます。 異なるルートフォルダを設定するにはカスタムルートフォルダの定義をご覧ください。

routing {
    static("static") {
        files("css") 
    }
}

上の例は/staticのURIに来た任意のリクエストを静的コンテンツのように扱うようktorに伝えます。 files("css")はそれらのファイルが配置されているフォルダを定義します。 つまりcssフォルダ配下の任意のファイルが配信されます。 つまり、/static/styles.cssといったリクエストはcss/styles.cssファイルを配信します。

フォルダに加え、fileを使うことで指定したファイルを含めることもできます。 実際の物理的なファイル名とURIのパス名が違った場合には、オプショナルの第二引数に実際の物理的なファイル名を指定することもできます。

routing {
    static("static") {
        files("css")
        files("js")
        file("image.png")
        file("random.txt", "image.png")
        default("index.html")
    }
}

defaultを使うことで、配信するデフォルトのファイルを指定することもできます。 例えば

/static をファイル名無しで呼び出した場合, index.htmlが配信されるようにすることができます。

カスタムのルートフォルダの定義

workingディレクトリ以外の異なるルートフォルダを指定するためには、 staticRootFolderFile型で値を指定します。

static("custom") {
    staticRootFolder = File("/system/folder/docs")
    files("public")
}

サブルートの定義

サブルートの定義もできます。 例えば/static/themesなどです。

static("static") {
    files("css")
    static("themes") {
        files("data")
    }
}

組み込みリソースの配信

静的コンテンツをリソースとしてアプリケーションに組み込む場合は、 resourceresources関数を使ってリソースから配信することができます:

static("static") {
    resources("css")
    resource("favicon.ico")
}

defaultに似たdefaultResourceというものもあり、フォルダに対し配信するデフォルトページの指定することができます。 staticRootFolderに似たstaticBasePackageというものもあり、静的コンテンツのベースリソースパッケージを指定することができます。

エラーハンドリング

リクエストされたコンテンツが見つからない場合、404 Not Foundが返されます。

コンテントタイプのカスタマイズ

ファイルが配信されるとき、コンテントタイプはContentType.defaultForFile(file)を使ってファイル拡張子から決定されます。 各ファイルタイプに対応するデータはktor-server-coreに配置されたmimelist.csvリソースファイルから取得されます。

内部実装

static関数は以下のように定義されています。

fun Route.static(remotePath: String, configure: Route.() -> Unit) = route(remotePath, configure)

これは本質的にはただすこし違った形でルート定義しているだけです。

静的コンテンツに対するHEADリクエストを扱う

KtorはHEADリクエストをデフォルトでは扱うことができません。 それゆえに静的コンテンツ機能もHEADリクエストを扱うことができません。 自動的にHEADリクエストを各GETルートごとに扱えるようにするには、 AutoHeadResponse Featureをインストールしてください。

fun Application.main() {
    // ...
    install(AutoHeadResponse) 
    // ...
}

デフォルトではHEADリクエストをハンドリングできないということは、 もしAutoHeadResponse Featureをインストールせずcurl -Icurl --headをGETルートに対して使った場合、 404 Not Foundが返ることになります