Избегайте глобальных изменений opener urllib в проверках прокси
Держите проверки прокси через urllib в пределах их собственного opener вместо замены процессных настроек маршрутизации и тайм-аутов по умолчанию.
from urllib.request import ProxyHandler, build_opener
def make_proxy_opener(proxy_uri):
return build_opener(ProxyHandler({
"http": proxy_uri,
"https": proxy_uri,
}))
opener = make_proxy_opener("http://proxy.example.net:8080")
# Use opener.open(destination, timeout=10) for this route.Вызывайте собственный метод open этого opener, когда маршрут относится к проверке. Конечная точка HTTP из примера может приходить из вашего сервиса или из списка HTTP-прокси для публичных проверок. Фрагмент иллюстрирует владение; он не определяет полную политику аутентификации или здоровья. Любые обработчики, специфичные для учётной записи, держите привязанными к предполагаемому клиенту.
urllib.request.install_opener() меняет процессное значение по умолчанию, которое используют последующие вызовы urlopen() на уровне модуля. Поэтому проверяльщик, перебирающий прокси, может оставить посторонние запросы на своей последней конечной точке. Временная установка и восстановление при очистке всё равно позволяют параллельным запросам выполняться во время общего изменения.
socket.setdefaulttimeout() аналогично меняет значения по умолчанию для создаваемых позже сокетов. Используйте тайм-аут на уровне операции, когда его должна получить только проверка.
Закрывайте ответы проверки и держите результаты конкретными: ответ с ошибкой HTTP не означает автоматически мёртвый слушатель прокси. Если синхронная проверка urllib используется в асинхронном сервисе, перенесите блокирующую работу в подходящий worker; это решение об исполнении не делает глобальное изменение opener изолированным.
Проверка должна возвращать своё наблюдение, не оставляя другую сетевую политику. Её собственный клиентский объект и ограниченная операция делают эту границу явной.