URL的netloc密码中是否允许使用问号?Python urllib.parse行为是否合规
1. URL密码部分不允许直接使用未编码的?
根据RFC 3986(当前URI/URL的正式标准)的相关规定:
URI的通用结构为scheme:[//authority]path[?query][#fragment],其中?是用于分隔路径(path)和查询参数(query)的通用保留分隔符,属于gen-delims字符集。
密码属于authority部分下的userinfo子段,RFC 3986第3.2.1节明确规定userinfo段允许的字符仅包含:
无保留字符(字母、数字、
-/./_/~)、百分号编码字符、子分隔符(!/$/&/'/(/)/*/+/,/;/=)以及冒号:
未编码的?不在允许范围内,要出现在密码中必须先做百分号编码为%3F。
2. Python urllib.parse.urlparse的解析行为符合标准
urllib的解析逻辑严格遵循RFC 3986的分隔符优先级规则,只要在URL中遇到未编码的?,就会将之后的内容全部识别为query段,不会将?归类到前面的authority段,所以你得到的实际解析结果是符合标准的。
你观察到SQLAlchemy、psycopg2能按预期解析,是因为数据库连接字符串的解析大多没有严格遵循通用URI标准,这类工具的自定义解析逻辑会优先匹配@作为userinfo和host的分隔符,所以允许@前出现?,属于非标准的兼容处理。
兼容方案
如果需要同时符合标准、满足业务密码带?的需求,只需要将密码中的?预先编码为%3F即可,编码后的示例URL为https://user:pass%3Fword@domain.name/path,urllib可以正确解析出预期结果。
内容的提问来源于stack exchange,提问作者Philip Couling
相关产品推荐
相关产品推荐

