Sttp Uri Avoid Decoding

552 views Asked by At

I am trying to download a file from a pre-signed 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>"

when I convert it to a Uri

val uri: Uri = uri"$url"

it decodes the %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>

When I try to get file with the decoded Uri I get this error message:

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

I think the uri decoding is causing problems because the curl on the %3A works but : doesn't.

Is there a way to avoid decoding the path? I couldn't find anything about it.

I am using the following sttp versions.

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

There are 1 answers

0
adamw On BEST ANSWER

You will need to change the encoding of the path segments in the parsed URI to a more strict one:

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

This is using sttp3, so might have to be edited slightly for sttp1. We are using the query encoding here, which according to rfc3986 escapes : in the query, but not in the path (where it's a legal character).

You could also try using quicklens to make this a bit more readable: