Sttp Uri 避免解码

Sttp Uri Avoid Decoding

我正在尝试从预签名的 s3 下载文件 url:

val url: String = "https://s3-us-west-2.amazonaws.com/exports.mandrillapp.com/<id>/activity-2021-02-01_00%3A34%3A43.zip?AWSAccessKeyId=<access_key>&Expires=1612744535&Signature=<signature>"

当我将其转换为 Uri 时

val uri: Uri = uri"$url"

它解码 %3Aactivity-2021-02-01_00%3A34%3A43.zip -> activity-2021-02-01_00:34:43.zip:

https://s3-us-west-2.amazonaws.com/exports.mandrillapp.com/<id>/activity-2021-02-01_00:34:43.zip?AWSAccessKeyId=<access_key>&Expires=1612744535&Signature=<signature>

当我尝试使用已解码的 Uri 获取文件时,我收到此错误消息:

The request signature we calculated does not match the signature you provided. Check your key and signing method.

我认为 uri 解码导致了问题,因为 %3A 上的 curl 有效,但 : 无效。

有没有办法避免解码路径?我找不到任何相关信息。

我正在使用以下 sttp 版本。

"com.softwaremill.sttp"       %% "core"                                 % "1.5.11",
"com.softwaremill.sttp"       %% "async-http-client-backend-future"     % "1.5.11"

您需要将已解析 URI 中路径段的编码更改为更严格的编码:

parsed.copy(
  pathSegments = Uri.AbsolutePath(parsed.pathSegments.segments
    .map(s => s.copy(encoding = QuerySegmentEncoding.All)).toList
  )
)

这是使用 sttp3,因此可能需要针对 sttp1 稍作编辑。我们在这里使用查询编码,根据 rfc3986 在查询中转义 :,但在路径(它是合法字符)中不转义。

您也可以尝试使用 quicklens 使其更具可读性: