HTTPリクエストをHTTPSにリダイレクト

Estimated reading time: 1 minute

このFeatureはHTTPコールを、処理を行う前に、対応するHTTPSロケーションへとリダイレクトする機能です。

デフォルトでは、リダイレクトは301 Moved Permanentlyですが、 302 Foundリダイレクトに設定することもできます。

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

使い方

fun Application.main() {
    install(HttpsRedirect)
    // install(XForwardedHeaderSupport) // Required when behind a reverse-proxy
}

上のコードはHttpsRedirect Featureをデフォルト設定でインストールします。

reverse-proxy背後にある場合、ForwardedHeaderSupportXForwardedHeaderSupport Featureをインストールする必要があります。 HttpsRedirect Featureが適切にHTTPSリクエストを検知することができるようにするためです。

設定

fun Application.main() {
    install(HttpsRedirect) {
        // The port to redirect to. By default 443, the default HTTPS port. 
        sslPort = 443
        // 301 Moved Permanently, or 302 Found redirect.
        permanentRedirect = true
    }
}

テスト

このFeatureを適用することで、 テストの動作が変わります。 このFeatureの適用後、handleRequestを実行する度に、リダイレクトレスポンスになります。 例え振る舞いがすでにテスト済みだったとしても、おそらく大抵の場合これは求めている挙動ではないです。

XForwardedHeaderSupport trick

このテスト で示されているように、 XForwardedHeaderSupportをインストールし、addHeader(HttpHeaders.XForwardedProto, "https")ヘッダーをリクエストに追加することができます。

@Test
fun testRedirectHttps() {
    withTestApplication {
        application.install(XForwardedHeaderSupport)
        application.install(HttpsRedirect)
        application.routing {
            get("/") {
                call.respond("ok")
            }
        }


        handleRequest(HttpMethod.Get, "/", {
            addHeader(HttpHeaders.XForwardedProto, "https")
        }).let { call ->
            assertEquals(HttpStatusCode.OK, call.response.status())
        }
    }
}

テスト時にFeatureをインストールしないか、あるいはアンインストールする

アンインストール:

application.uninstall(HttpsRedirect)

インストールを防ぐ方法:

// The function referenced in the application.conf
fun Application.mymodule() {
    mymoduleConfigured()
}

// The function referenced in the tests
fun Application.mymoduleForTesting() {
    mymoduleConfigured(installHttpsRedirect = false)
}

fun Application.mymoduleConfigured(installHttpsRedirect: Boolean = true) {
    if (installHttpsRedirect) {
        install(HttpsRedirect)
    }
    // ...
}

このケースにおいては、mymoduleForTestingの代わりにmymoduleを呼び出す別のテストを作成することもできます。 それによってHttpsRedirect機能がインストールされることと、テストにおいて行えないことの検証も行うことができます。

この機能を使ったとき無限リダイレクトになる場合

XForwardedHeaderSupportForwardedHeaderSupportをインストール済みですか? このFAQエントリをチェックしてみてください。