Ktor 3.5.0 最新变化
Ktor 3.5.0 在服务器和客户端方面带来了一系列改进。此功能版本的亮点包括:
Ktor Server
对 RFC 7616 摘要身份验证的支持
Ktor 3.5.0 更新了 digest 身份验证提供程序以符合 RFC 7616,提高了安全性并增加了对现代摘要功能的支持。
此版本引入了以下更改:
- 您现在可以使用
algorithms属性配置多个哈希算法。当指定多个值时,Ktor 会发送多个WWW-Authenticate标头,以便客户端可以选择支持的最强选项。 - 引入了
DigestAlgorithm和DigestQop枚举来替代基于字符串的配置。 digestProvider {}lambda 现在接收一个algorithm形参,允许您动态计算正确的摘要。- 根据 RFC 7616,
qop形参现在包含在身份验证质询中。 - 增加了对基于会话的算法的支持,例如
SHA-256-sess和SHA-512-256-sess。 - 增加了对 RFC 7616 用户名哈希 (
userhash) 的支持,以提高隐私保护。
以下示例展示了如何从旧版配置迁移到符合 RFC 7616 标准的 API:
现有配置无需更改即可继续工作。但是,对于新应用程序,建议:
- 使用安全的算法,例如
SHA-512-256或SHA-256。 - 更新
digestProvider以使用新的algorithms形参。 - 除非为了兼容旧版客户端,否则请避免使用基于
MD5的算法。
有关完整指南,请参阅 Ktor Server 中的摘要身份验证。
自定义提供程序中的挂起 .authenticate() 重载
自定义身份验证提供程序现在可以实现 DynamicProviderConfig.authenticate() 函数的挂起版本。.authenticate() 函数接受一个挂起 lambda,因此您可以直接在身份验证中调用协程 API:
install(Authentication) {
provider("custom") {
authenticate { context ->
delay(10.milliseconds)
context.principal(null)
}
}
}根配置数据类映射
ApplicationConfig 现在提供了一个 .getAs() 函数,用于将整个配置反序列化为一个数据类。
以前,反序列化仅限于单个属性,需要通过 .property() 函数进行访问。有了根级支持,您可以直接将完整的配置结构映射到单个数据类:
必需请求参数辅助函数
Ktor 3.5.0 引入了一组新的扩展函数,简化了从 ApplicationCall 访问必需请求数据的过程。
以前,验证必需的请求数据通常需要重复的 null 检查和带标签的返回。为了改进这一工作流,Ktor 现在提供了以下新的扩展函数:
ApplicationCall.requireQueryParameter()—— 从请求 URL 中检索必需的查询形参。如果形参缺失则抛出异常。ApplicationCall.requireHeader()—— 检索必需的 HTTP 标头值。如果请求中不存在该标头则抛出异常。ApplicationCall.requireCookie()—— 检索必需的 cookie 值,可以选择使用指定的编码对其进行解码。如果 cookie 缺失则抛出异常。RoutingCall.requirePathParameter()—— 从路由定义中检索必需的路径形参。如果匹配的路由中不存在该形参则抛出异常。
每个函数都会返回一个非 null 值,或者在值缺失时抛出 MissingRequestParameterException。
ktor-network 的 ES 模块兼容性
我们修复了在启用 ES 模块时无法使用 ktor-network 及其所有依赖模块的问题。
为了帮助防止未来的回归,我们的 JavaScript 测试基础架构现在默认针对 ES2015 和 ES 模块。
有关 Kotlin/JS 模块系统和 ES2015 支持的更多信息,请参阅:
仅在修改时发送会话 cookie
Ktor 3.5.0 为 Sessions 插件引入了一个新选项,仅在会话数据发生变化时发送该数据(例如,对于基于 cookie 的会话发送 Set-Cookie 标头)。
默认情况下,会话数据会在每次响应时发送,以保留现有行为。若要仅在修改时发送,请在会话 cookie 配置中启用 sendOnlyIfModified 标志:
install(Sessions) {
cookie<MySession>("SESSION") {
sendOnlyIfModified = true
}
}自定义 SSE 心跳事件
此版本为 Ktor 服务器端 SSE 支持引入了一个新选项,允许您使用事件提供程序函数完全自定义心跳事件:
heartbeat {
period = 30.milliseconds
eventProvider = { ServerSentEvent(data = "ts=${Clock.System.now()}") }
}这使得定期发送自定义心跳有效负载成为可能,例如时间戳和状态信息。
Ktor Client
OkHttp 和 Apache5 引擎中的自定义 DNS 解析器
Ktor 3.5.0 在 OkHttp 和 Apache5 客户端引擎中增加了对配置自定义 DNS 解析器的一等支持。
以前,您需要通过访问引擎特定的内部结构来配置自定义 DNS 解析,例如 OkHttp 中的 config {} 或 Apache5 中的 configureConnectionManager { setDnsResolver(...) }。Ktor 现在在每个引擎上公开了专门的配置属性,以提供一致且类型安全的 API。
OkHttp
您现在可以使用 OkHttpConfig.dns 属性在 OkHttp 中配置自定义 DNS 解析器:
HttpClient(OkHttp) {
engine {
dns = Dns { hostname -> listOf(InetAddress.getByName("127.0.0.1")) }
}
}如果您不配置 dns 属性,OkHttp 引擎将继续使用 OkHttp 默认的 Dns.SYSTEM 解析器。
Apache5
您现在可以使用 Apache5EngineConfig.dnsResolver 属性在 Apache5 中配置自定义 DNS 解析器:
HttpClient(Apache5) {
engine {
dnsResolver = SystemDefaultDnsResolver.INSTANCE
}
}如果未配置 dnsResolver 属性,Apache5 引擎将继续使用 Apache 客户端默认的 DNS 解析器。
