Amazon S3使用Amazon Java SDK和额外/字符预签名的URL

时间:2012-02-12 10:12:59

标签: amazon-s3 urlencode

我一直在创建Presigned HTTP PUT URL,一切都运行良好,直到我想开始在S3中使用“文件夹”;我希望关键字有'/'。

现在,当我发送HTTP PUT请求时,由于'/'可能更改为%2F,我得到Signature不匹配...如果我在创建预先签名的URL之前转义字符它很有效,但是亚马逊控制台管理员不理解它并将其显示为一个文件而不是子文件夹。

有什么想法吗?

P.S。
使用带有POCO NET库的C ++发送HTTP PUT请求。

EDIT
我正在使用C ++中的Poco HttpRequest到我的Java Web服务器来生成一个签名的URL(在响应中返回)。
然后,C ++再次使用此URL将文件放入s3中使用Poco 问题是从Web服务器返回的URL是通过Poco URI对象解析的,这些对象自动解码了s3对象密钥,从而改变了它。
考虑到这一点,我能够解决我的问题。

1 个答案:

答案 0 :(得分:2)

整蛊 - 我会尝试自下而上。

免责声明:我在视觉上检查 Poco 库而不是实际调试代码示例,这样可以更快地生成更可靠的结果,请参阅下文;)< / p>

分析

  

如果我在创建预签名网址之前将其转义,则可以使用   很棒,但亚马逊控制台管理层并不了解它   并将其显示为一个文件而不是子文件夹。

后者源于S3实际上在存储级别上没有文件夹概念,请参阅例如Index Document Support中的索引文档和文件夹部分:

  

存储在Amazon S3中的对象存储在扁平容器中,即   一个Amazon S3存储桶,它不提供任何层次结构   组织,类似于文件系统。但是,您可以创建一个   逻辑层次结构使用对象键名称并使用这些名称进行推断   包含这些对象的逻辑文件夹。

这正是AWS Management Console在这里所做的事情:

  

AWS管理控制台还支持文件夹的概念   使用前面示例中使用的相同键命名约定。

然而,您对/被编码为%2F的假设的测试证明,这确实是 Poco :: Net 是在执行HTTP PUT请求时对URL进行编码。

  • (实际上有点惊讶的是, AWS Java SDK 似乎在这里为/%2F生成了不同的网址,因为最近有关{/的分析3}}似乎表明了 AWS .NET SDK 的相应规范化,详见下文。)

潜在解决方案

为了让你的场景按照需要工作,你需要弄清楚URL的编码方式 - 我原则上可以想到两个组件:

波索::网络

找出为什么 Poco :: Net 编码不同于S3的URL(如果有的话,见下文)最好通过调试代码完成,这是我开始的地方:

Why is my S3 pre-signed request invalid when I set a response header override that contains a “+”?依次使用类HTTPRequest会自动对传递给它的所有URI和URI部分执行一些规范化,特别是百分比编码字符被解码。另一种方法是由方法URI处理,其中事情变得有趣并且要求断点,请参阅encode()

  • 第575行。 - 这里 encode()确实有它的魔力,它实际上似乎已经存在,只要函数中的代码和通过保留的参数传入的各种字符都包含违规{{1}}(见第47行ff。对于使用中的各个常数)
  • 因此你可能想在这个函数中设置一个断点并回溯一下callstack以找出实际上正在进行编码的代码,这可能根本不会产生违法者,见下文。

Java =&gt; C ++过渡

您尚未指定,实际上使用哪个频道将AWS Java SDK生成的预签名URL依次传递给C ++。鉴于 Poco :: Net 功能的代码审查(请注意,仅我是视觉检查,我还没有自己调试)得出结论,在库本身中无法识别明显的罪犯,因此它似乎更有可能已经进入你的C ++层编码(当然通过调试很容易验证) - 你是否偶然使用这些组件之间的任何类型的Web服务?

祝你好运!