1 回答

TA贡献1804条经验 获得超7个赞
RFC 3986第 6.2.2.1 节关于 URI 的说明:
[...]的方案和主机是不区分大小写的,因此应被归一化到小写[...]。
恕我直言,您的名称解析行为不正确,似乎有一个与 Docker 网络区分大小写相关的未决问题,我认为这里正在使用。
requests
, 分别 urllib3
, 尊重 RFC 建议,至少对于 HTTP 方案连接。就requests
目前而言,似乎有四个相关的地方将主机名转换为小写。
urllib3
的实用程序类Url
,它在requests
'PreparedRequest
实例执行prepare_url
方法时发挥作用。urllib3
1.22 版还lower()
调用了ConnectionPool
基类初始值设定项中的主机名。_ipv6_host
显然,此规范化已移至1.23 版的功能。
使用monkeypatching我似乎已经能够强制requests
,resp。urllib3
, 保留 URL 的主机名部分不变:
import functools
import urllib3
def _custom_key_normalizer(key_class, request_context):
# basically a 1:1 copy of urllib3.poolmanager._default_key_normalizer
# commenting out
# https://github.com/urllib3/urllib3/blob/master/src/urllib3/poolmanager.py#L84
#context['host'] = context['host'].lower()
class ConnectionPool(object):
def __init__(self, host, port=None):
# complete copy of urllib3.connectionpool.ConnectionPool base class
# I needed this due to my urllib3 version 1.22.
# If you have urllib3 >= 1.23 this is not necessary
# remove the .lower() from
# https://github.com/urllib3/urllib3/blob/1.22/urllib3/connectionpool.py#L71
self.host = urllib3.connectionpool._ipv6_host(host)
urllib3.util.url.NORMALIZABLE_SCHEMES = (None,)
# This is needed for urllib3 >= 1.23. The connectionpool module imports
# NORMALIZABLE_SCHEMES before we can patch it, so we have to explicitly patch it again
urllib3.connectionpool.NORMALIZABLE_SCHEMES = (None,)
urllib3.poolmanager.key_fn_by_scheme['http'] = functools.partial(_custom_key_normalizer,
urllib3.poolmanager.PoolKey)
# just for urllib3 < 1.23
urllib3.connectionpool.ConnectionPool = ConnectionPool
# do not use anything that would import urllib3 before this point
import requests
url = f'http://gateway.Niedersachsen/api/wfs/insertGeometry'
r = requests.get(url)
我假设成功,因为我的错误消息显示连接池中使用的主机,仍然使用初始大写:
requests.exceptions.ConnectionError: HTTPConnectionPool(host='gateway.Niedersachsen', port=80): [...]
注意:直接
使用可能有更简单的方法urllib3;我没有研究过这个。
另外,如果有人知道使用 保留主机大写的更直接方法requests,请告诉我。
添加回答
举报