0

我正在尝试从预签名的 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"

它解码%3A. activity-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 解码会导致问题,因为 curl 可以%3A正常工作,但:不能。

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

我正在使用以下 sttp 版本。

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

1 回答 1

1

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

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

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

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

于 2021-02-01T07:24:25.717 回答