压缩
所需依赖项:io.ktor:ktor-server-compression
代码示例: compression
Ktor 提供了通过使用 Compression 插件来压缩响应主体和解压缩请求主体的功能。
使用 Compression 插件,您可以:
- 使用不同的压缩算法,包括
gzip、zstd和deflate。 - 指定压缩数据的必要条件,例如内容类型或响应大小。
- 根据特定的请求参数压缩数据。
请注意,
Compression插件目前不支持SSE响应。
要了解如何在 Ktor 中提供预压缩的静态文件,请参阅预压缩文件。
添加依赖项
要使用 Compression,您需要在构建脚本中包含 ktor-server-compression 构件:
要包含 Zstandard 压缩,请添加 ktor-server-compression-zstd 依赖项:
安装 Compression
要将 Compression 插件安装到应用程序,请将其传递给指定
install 函数。以下代码片段展示了如何安装 Compression ... - ... 在
embeddedServer函数调用内部。 - ... 在显式定义的
module(它是Application类的扩展函数)内部。
这将在服务器上启用 gzip、deflate 和 identity 编码器。在下一章中,我们将了解如何仅启用特定的编码器并配置压缩数据的条件。请注意,如果需要,每个添加的编码器都将用于解压缩请求主体。
配置压缩设置
您可以通过多种方式配置压缩:仅启用特定的编码器、指定其优先级、仅压缩特定的内容类型,等等。
添加特定编码器
要仅启用特定的编码器,请调用相应的扩展函数,例如:
install(Compression) {
gzip()
deflate()
zstd()
}您可以通过设置 priority 属性来为每个压缩算法指定优先级:
install(Compression) {
gzip {
priority = 0.9
}
deflate {
priority = 1.0
}
zstd {
priority = 0.8
}
}在上面的示例中,deflate 具有更高的优先级值,并且优先于 gzip 和 zstd。请注意,服务器首先查看 Accept-Encoding 标头中的质量值,然后考虑指定的优先级。
配置内容类型
默认情况下,Ktor 不压缩特定的内容类型,例如 audio、video、image 和 text/event-stream。您可以通过调用 matchContentType 来选择要压缩的内容类型,或者通过使用 excludeContentType 从压缩中排除所需的媒体类型。以下代码片段展示了如何使用 gzip 压缩 JavaScript 代码,并使用 deflate 压缩所有文本子类型:
install(Compression) {
gzip {
matchContentType(
ContentType.Application.JavaScript
)
}
deflate {
matchContentType(
ContentType.Text.Any
)
}
}您可以在此处找到完整示例:compression。
配置响应大小
Compression 插件允许您对大小不超过指定值的响应禁用压缩。为此,请将所需的值(以字节为单位)传递给 minimumSize 函数:
install(Compression) {
deflate {
minimumSize(1024)
}
}指定自定义条件
如有必要,您可以使用 condition 函数提供自定义条件,并根据特定的请求参数压缩数据。以下代码片段展示了如何为指定的 URI 压缩请求:
install(Compression) {
gzip {
condition {
request.uri == "/orders"
}
}
}HTTPS 安全性
启用压缩的 HTTPS 容易受到 BREACH 攻击。您可以使用各种方法来缓解此攻击。例如,只要 referrer 标头指示跨站请求,您就可以禁用压缩。在 Ktor 中,这可以通过检查 referrer 标头值来实现:
install(Compression) {
gzip {
condition {
request.headers[HttpHeaders.Referrer]?.startsWith("https://my.domain/") == true
}
}
}Zstandard 压缩级别
您可以使用 level 参数配置 zstd 的压缩级别。默认压缩级别为 3,但您可以根据需要进行调整。
install(Compression) {
// 默认为 level = 3
zstd(level = 20)
}实现自定义编码器
如有必要,您可以通过实现 ContentEncoder 接口来提供您自己的编码器。请参阅 GzipEncoder 作为实现的示例。
