RFC 3986 В разделе 6.2.2.1 говорится об URI:
[...] схема и хост не чувствительны к регистру , и поэтому следует нормализовать в нижнем регистре [...].
ИМХО, ваше разрешение имени ведет себя некорректно, и, кажется, существует открытая проблема , связанная с чувствительностью к регистру для сети Docker, которая, как я предполагаю, используется здесь.
requests
, соотв. urllib3
, соблюдает рекомендацию RFC, по крайней мере для соединений по схеме HTTP. Что касается requests
, то, по-видимому, существует четыре соответствующих места, где имена хостов преобразуются в нижний регистр.
urllib3
служебный класс Url
, который вступает в игру, когда экземпляр requests
'PreparedRequest
выполняет метод prepare_url
.
- функция
_default_key_normalizer
, вызываемая PoolManager
через отображение key_fn_by_scheme
- в случае, если ваше имя хоста содержит не-ASCII-символы, оно также проходит через кодировку IDNA, но в вашем примере это не так.
urllib3
версия 1.22 также имела вызов lower()
для имени хоста в инициализаторе базового класса ConnectionPool
. Эта нормализация была перенесена в функцию _ipv6_host
начиная с версии 1.23.
Используя monkeypatching, я, кажется, смог заставить requests
, соответственно. 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
, , пожалуйста, , дайте мне знать.