如何解决如何防止Akka Http重定向请求中URI的百分比解码?
我正在使用Akka Http处理存储在GCS(Google云存储)中的文本资源的签名url重定向。基本上,我在GCS中有一些文件,希望在请求时随API一起提供。不幸的是,该资源的路径中有一个带有=
字符的子目录,类似于:https://storage.googleapis.com/path_start/more_path/format=avro/still_more_path/filename.avro
。
Google存储空间的signUrl
方法将已签名的网址中的=
字符编码为%3D
。我已验证使用此签名的url可以访问GCS中的文件(点击即可开始下载)。问题是,当Akka Http根据请求重定向此签名的url时,它将其解码回等号。这会导致来自GCS的SignatureDoesNotMatch
错误:
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message>
val signedUrl = cloudStorageService.getSignedUrl(bucketId,filePath)
logger.info(s"signedUrl: $signedUrl")
redirect(signedUrl,TemporaryRedirect)
和我的cloudStorageService.getSignedUrl
方法在此处分别定义:
def getSignedUrl(bucket: String,path: String,expiration: Option[Int] = None): String = {
val maxLifetime = 60 * 60 * 24 * 7
val lifetime = expiration.getorElse(maxLifetime)
val cappedExpiration = Math.min(lifetime,maxLifetime)
val blobInfo = BlobInfo.newBuilder(BlobId.of(bucket,path)).build
storage.signUrl(blobInfo,cappedExpiration,TimeUnit.SECONDS,Storage.SignUrlOption.withV4Signature).toString
}
第一个代码段中的日志记录语句告诉我,已签名的URL是使用%3D
生成的,但是重定向的URL已被百分比解码回=
,从而导致SignatureDoesNotMatch
错误。
此行为是Akka Http的标准行为。根据{{3}}(针对Uri类),所有成员均代表百分比解码元素。可以使用原始查询字符串构造uri,但在我的情况下,编码字符出现在uri路径本身中,而不是查询中。
所以我的问题是,有什么方法可以使Akka Http重定向此签名的url,而无需对路径进行百分比解码?还是我弄错了,还有另一种方法可以解决这个问题?
解决方法
您可能想要“手动”创建重定向响应,而不是使用“ redirect”指令。指令实现为:
HttpResponse(
status = redirectionType,headers = headers.Location(uri) :: Nil,entity = redirectionType.htmlTemplate match {
case "" => HttpEntity.Empty
case template => HttpEntity(ContentTypes.`text/html(UTF-8)`,template format uri)
}
您可以引入自己的headers.Location(uri)
来代替RawHeader
来构建Location
标头。您可以在方案中将实体留空。
(相关文档:https://doc.akka.io//docs/akka-http/current/routing-dsl/directives/route-directives/redirect.html)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。