Skip to main content

HTTP_PROXY и NO_PROXY: проверка без сети

Updated 4 min readMarkdown

Переменная с адресом прокси есть, но программа ведёт себя иначе, чем ожидается. До проверки пароля и покупки другого тарифа полезно ответить на более узкий вопрос: какие параметры видит именно этот клиент?

Ниже воспроизводимый опыт с двумя функциями стандартной библиотеки Python. Он проверяет выбор переменных и исключений без запроса к сайту. Все адреса учебные; настоящие логины, пароли и настройки вашей машины в вывод не попадают.

Материал подготовлен Portproof, сервисом прокси, eSIM и SMS. Это самостоятельная техническая заметка нашей публикации. Мы не измеряем здесь скорость соединения и не проверяем доступность какого-либо сайта. При подготовке использовался ИИ; границы проверки и источники указаны в тексте.

Сначала отделите три решения

Для обращения к HTTPS-сайту приложению нужно выбрать настройки для схемы назначения, определить, попадает ли узел в исключения, и только затем выполнить соединение. Наличие HTTP_PROXY ещё не доказывает, что HTTPS-запрос использует этот адрес. Значение http://… у HTTPS-прокси может быть правильным: это схема подключения к шлюзу, а не схема целевого сайта.

Есть и другой уровень: переменные вашего терминала не обязательно совпадают с окружением IDE, контейнера, службы или фонового задания. Проверка в соседнем окне терминала исследует другой процесс. Не выводите всё окружение рабочего процесса в общий журнал: среди переменных могут быть секреты.

Наш опыт использует getproxies_environment() и proxy_bypass_environment() из urllib.request. Это вспомогательные функции конкретной реализации CPython. Публичный getproxies() может дополнительно читать системные настройки, когда переменные не дали конфигурацию. Мы эту ветку не запускаем. Результат нельзя автоматически переносить на Requests, Node.js, браузер или Docker.

Что проверить в выборе переменных

В синтетическом окружении задаём только нужные значения. Контекст patch.dict(..., clear=True) временно скрывает исходное окружение внутри отдельного тестового процесса и восстанавливает его после проверки. Код ничего не записывает в профиль оболочки или настройки системы.

Входные данные Результат проверяемой функции
Только HTTP_PROXY Адрес читается для схемы HTTP
Разные HTTP_PROXY и http_proxy Выбирается значение в нижнем регистре
HTTP_PROXY вместе с REQUEST_METHOD Значение HTTP в верхнем регистре игнорируется
http_proxy вместе с REQUEST_METHOD Значение в нижнем регистре сохраняется
Непустая HTTP_PROXY и пустая http_proxy Пустое нижнее значение убирает настройку

Особенность REQUEST_METHOD связана с CGI и обработкой входных заголовков. Не удаляйте защитный признак из рабочего окружения ради прохождения теста. Если приложение должно использовать явную конфигурацию, настройте её предусмотренным клиентом способом.

Исключение — отдельное решение

Следующий небольшой фрагмент можно запустить без сети. Он показывает именно результат функции, которая проверяет список исключений:

from urllib.request import proxy_bypass_environment

cases = [
    ("api.example", "example", True),
    ("notexample", "example", False),
    ("api.example:8443", "example:8443", True),
    ("api.example:443", "example:8443", False),
    ("api.example", "*", True),
    ("192.0.2.7", "192.0.2.0/24", False),
]
for host, no_proxy, expected in cases:
    actual = proxy_bypass_environment(host, {"no": no_proxy})
    assert actual is expected, (host, no_proxy)
    print(host, no_proxy, actual)

True здесь означает попадание в исключение для прямого маршрута. Это не подтверждение успешного соединения напрямую. Поддомен api.example совпадает с суффиксом example, а похожая строка notexample — нет. Если в правиле указан порт, не считайте его правилом для любого порта.

Проверка с CIDR намеренно показывает границу опыта: данная функция не разворачивает подсеть 192.0.2.0/24 в набор адресов. Другой клиент может трактовать такой список иначе. Поэтому копирование одного NO_PROXY во все инструменты требует отдельной проверки каждого клиента.

31 октября 2026 года полный локальный набор из 13 сценариев прошёл на CPython 3.12.14. Обращения к сокетам были запрещены тестом; их число осталось нулевым. Проверена логика выбора синтетических настроек. DNS, операционная система, авторизация, туннель CONNECT и реальный маршрут запроса этим опытом не проверены.

Как применить результат к своей задаче

Запишите имя клиента и его версию, способ запуска, схему целевого URL и источник настроек. Для исключений сохраните только учебный аналог имени узла; пароль для такого расследования не нужен. Затем выберите один источник настройки и повторите небольшой разрешённый запрос в самом приложении.

Если нужен пример с явным обработчиком и авторизацией, используйте инструкцию по прокси в Python urllib. Когда curl работает, а приложение нет, порядок сравнения двух клиентов помогает отделить окружение от сетевой ошибки. Общие поля разобраны в настройках прокси.

Источник для поведения публичных интерфейсов: документация Python 3.12. Версию используемой библиотеки проверяйте отдельно: этот опыт — зафиксированная проверка, а не обещание одинакового поведения всех HTTP-клиентов.

No comments yet. Be the first to comment.

More from this blog