符合亚马逊AWS规范的URL编码查询字符串

3
我目前正在实现一个应用程序来生成Amazon AWS Signature Version 4签名(有关签名过程的详细信息,请参阅此页面:http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html)。方便起见,亚马逊还为这些签名提供了一个测试套件。然而,有一个测试案例我真的搞不清楚。请注意,我的问题仅涉及签名过程的第一步(生成规范请求),特别是创建规范查询字符串。测试案例输入HTTP请求如下:
POST /?@#$%^&+=/,?><`";:\|][{} =@#$%^&+=/,?><`";:\|][{}  http/1.1
Date:Mon, 09 Sep 2011 23:36:00 GMT
Host:host.foo.com

这是规范请求的预期结果:
POST
/
%20=%2F%2C%3F%3E%3C%60%22%3B%3A%5C%7C%5D%5B%7B%7D&%40%23%24%25%5E=
date:Mon, 09 Sep 2011 23:36:00 GMT
host:host.foo.com

date;host
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

第三行规范请求表示已编码的查询字符串。但是,即使按照Sig V4文档中规定的规则,我也不太明白它们是如何从输入中获取的:
要构建规范查询字符串,请完成以下步骤:
根据以下规则对每个参数名称和值进行URI编码:
不要对RFC 3986定义的任何未保留字符进行URL编码:
A-Z、a-z、0-9、连字符(-)、下划线(_)、句点(.)和波浪号(~)。
将所有其他字符使用%XY进行百分号编码,其中X和Y是十六进制字符(0-9和大写字母A-F)。
例如,空格字符必须编码为%20(不使用“+”,因为某些编码方案使用),扩展的UTF-8字符必须采用%XY%ZA%BC的形式。
按字符代码(即严格按ASCII顺序)排序编码后的参数名称。例如,以大写字母F(ASCII代码70)开头的参数名称优先于以小写字母b(ASCII代码98)开头的参数名称。
通过从排序列表中的第一个参数名开始构建规范查询字符串。
对于每个参数,附加URI编码的参数名称,后跟字符'='(ASCII代码61),后跟URI编码的参数值。对于没有值的参数,请使用空字符串。
在除列表中的最后一个值之外的每个参数值后附加字符'&'(ASCII代码38)。
有人能解释一下吗?提前感谢!
1个回答

2
我想我可能已经弄清楚了。将查询字符串@#$%^&+=/,?><``";:\|][{} =@#$%^&+=/,?><``";:\|][{}分解为键/值对(按出现顺序):
  1. @#$%^,值
  2. +,值/,?><``";:\|][{}
  3. @#$%^,值
  4. +,值/,?><``";:\|][{}
根据https://dev59.com/aXI-5IYBdhLWcg3wpqIK#1746566,关于重复键的处理没有标准,因此看起来亚马逊选择要么忽略要么覆盖它们(在这个测试用例中不可能确定重复键的值是否相同)。
最后,考虑到第二次出现@#$%^之前的=,我认为它被解析为一个键/值对,其中键值为null,因此被完全删除。

就是这样!真的非常感谢。现在一切都清楚了。只有一个小修正:由于查询字符串中间有空格,第三个和第四个键被丢弃了。也许你可以编辑一下上面的内容?尽管如此,我会将其标记为正确答案 :) - Zasha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接