在Ktor中用缓存头响应图像

时间:2019-09-17 16:56:31

标签: caching kotlin ktor

为Ktor提供的静态图像发送回高速缓存头的正确方法是什么?

我有以下Ktor设置:

在我的main中:

embeddedServer(
        Netty,
        watchPaths = listOf("module"),
        module = Application::module,
        port = if (ENV.env == LOCAL) {
            8080
        } else {
            80
        }
    ).apply {
        start(wait = true)
    }

然后在主外部:

fun Application.module() {
    if (ENV.env != LOCAL) {
        install(ForwardedHeaderSupport)
        install(XForwardedHeaderSupport)
        install(HttpsRedirect)
    }
    install(CachingHeaders) {
        options { outgoingContent ->
            when (outgoingContent.contentType?.withoutParameters()) {
                ContentType.Image.Any -> CachingOptions(CacheControl.MaxAge(maxAgeSeconds = 30 * 24 * 60 * 60))
                else -> null
            }
        }
    }
    install(Compression) {
        gzip {
            priority = 1.0
        }
        deflate {
            priority = 10.0
            minimumSize(1024) // condition
        }
    }

    routing {
        static("/js/") {
            resources("/js/")
        }

        static("/css/") {
            resources("/css/")
        }

        static("/favicons") {
            resources("/favicons/")
        }

        static("/img/") {
            resources("/static/img/")
            resources("/static/images/")
            resources("/background/")
            resources("/logos/")
            resources("/icons/")
        }
    }
}

图像又回来了,没有缓存头,有什么想法吗?

enter image description here

更新

ContentType.Image.Any更改为ContentType.Image.JPEG似乎可行。查看Image的源代码,它似乎映射到ContentType(image*),但根本不匹配任何图像类型。

install(CachingHeaders) {
    options { outgoingContent ->
        when (outgoingContent.contentType?.withoutParameters()) {
            ContentType.Image.JPEG -> CachingOptions(
                cacheControl = CacheControl.MaxAge(
                    mustRevalidate = false,
                    maxAgeSeconds = 30 * 24 * 60 * 60,
                    visibility = CacheControl.Visibility.Public
                )
            )
            else -> null
        }
    }
}

同时提出了一个错误: https://github.com/ktorio/ktor/issues/1366

2 个答案:

答案 0 :(得分:2)

结果是,正在对*而不是实际文件类型进行标准的eqauls检查,因此使用match可以解决该问题:

install(CachingHeaders) {
    options { outgoingContent ->
        if (outgoingContent.contentType?.withoutParameters()?.match(ContentType.Image.Any) == true) {
            CachingOptions(
                cacheControl = CacheControl.MaxAge(
                    mustRevalidate = false,
                    maxAgeSeconds = 6 * 30 * 24 * 60 * 60,
                    visibility = CacheControl.Visibility.Public
                )
            )
        } else {
            null
        }
    }
}

答案 1 :(得分:0)

您可以使用https://ktor.io/servers/features/caching-headers.html

通过内容类型设置缓存头。