Sttp Uri избегает декодирования

#scala #https #uri #decoding #sttp

#scala #https #uri #декодирование #sttp

Вопрос:

Я пытаюсь загрузить файл с предварительно подписанного URL-адреса s3:

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

когда я преобразую его в Uri

 val uri: Uri = uri"$url"
 

он декодирует : . activity-2021-02-01_00:34:43.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>amp;Expires=1612744535amp;Signature=<signature>
 

Когда я пытаюсь получить файл с декодированным Uri, я получаю это сообщение об ошибке:

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

Я думаю, что декодирование uri вызывает проблемы, потому что curl : работает, но : не работает.

Есть ли способ избежать расшифровки пути? Я ничего не смог найти по этому поводу.

Я использую следующие версии sttp.

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

Ответ №1:

Вам нужно будет изменить кодировку сегментов пути в проанализированном URI на более строгую:

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

Здесь используется sttp3, поэтому, возможно, придется немного отредактировать для sttp1. Здесь мы используем кодировку запроса, которая, согласно rfc3986, экранируется : в запросе, но не в пути (где это юридический символ).

Вы также можете попробовать использовать quicklens, чтобы сделать это немного более читаемым: