得之我幸 失之我命

when someone abandons you,it is him that gets loss because he lost someone who truly loves him but you just lost one who doesn’t love you.

Py3.6 迁到 3.7 urllib.parse.quote 的坑

在写一个通过网关发 post 请求的时候发生了一件揪心的事,耗时 3 天,才初见眉目,在我的电脑上网关旧返回一个“摘要身份认证错误”,无法进行下一步,但是关键是其他人的电脑上可以正常跑通,想来问题就在于我的 python 版本了。

在服务器上部署了代码,看了 python 版本是 3.6 的,可以跑,我本机的环境是 3.7 的,报错,那么问题来了,到底是哪个位置错了呢。

通过打印两个版本下跑的结果以及网关需要签名的参数,发现了端倪

1
msg = urllib.parse.quote_plus(msg, safe='')

两个版本下,msg 在被编码的时候出现了差异,3.6 版本中,~ 被编码成了 %7E,而 3.7 中则是不编码,所以导致了一系列的问题,于是去查了 3.7 的 changelog,果然有猫腻

bpo-16285: urllib.parse.quote is now based on RFC 3986 and hence includes ‘~’ in the set of characters that is not quoted by default.

再仔细看 issue,发现 3.7 Update urllib quoting to RFC 3986,RFC3986 中明确废除了 RFC2396,而 RFC3986 中提到

RFC 3986 (http://www.ietf.org/rfc/rfc3986.txt) says:
For consistency, percent-encoded octets in the ranges of ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved characters by URI normalizers.

所以默认不对 ~ 进行编码。

be yourself, everyone else is already taken.