缘起是一个http签名方法,客户端对 http 的参数签名,然后服务器验证签名。然后突然测试出当提交的内容中含有空格时,服务器就验签失败。
查询了客户端签名的过程数据,然后和服务器的验签步骤查看了下,居然是客户端在签名前数据中的空格被格式化为了 "%20", 而 golang 服务器是用 url.Values.Encode() 方法导致空格变成了 "+" 号。
问题就是这儿了, 空格无论是哪种 escape, 似乎都有标准可依。两个标准,难分对错。而且golang 还提供了两种 escape 标准实现方法:
- PathEscape: 空格会转为 %20
- QueryEscape: 空格会转为 +
而 url.Values.Encode() 内部使用的就是 QueryEscape() 方法,所以最终解决方案是在 url.Encode() 后对 + 替换为 %w0:
strings.Replace(url.Values.Encode(), "+", "%20", -1)