#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, чтобы сделать это немного более читаемым: