Верстакфорум практиков
рекламаiprazon: приватные серверные адреса IPv4 и SOCKS5, безлимитный трафик, бесплатный тест до 2 часов
ФорумНастройка и подключение

Переменные окружения: почему регистр имён иногда решает

nastroyka_pro
nastroyka_pro
Ветеран
сообщений 2110
с мар
22 декабря, 17:47первое сообщение

Ловил вчера полтора часа. На сервере прописано HTTP_PROXY, curl гонит запросы напрямую, питон через посредника ходит спокойно. Одна машина, одна оболочка, разные результаты.

Оказалось, curl смотрит имя строчными буквами, а заглавный вариант для схемы http он игнорирует намеренно. Для https читает обе формы.

Разложу, что накопал, заодно спрошу, кто ещё где на этом спотыкался.

iron_shell
iron_shell
Знаток
сообщений 1050
с июн
1 мая, 08:04#2

Причина у этого странного поведения историческая, и сидит она в том, как заголовки запроса попадают в окружение обработчика.

Когда веб-сервер запускает обработчик страницы, он кладёт все заголовки в переменные: X-Forwarded-For становится HTTP_X_FORWARDED_FOR, User-Agent становится HTTP_USER_AGENT. Схема простая: приставка HTTP_ плюс имя заголовка заглавными.

Дальше очевидное. Кто угодно снаружи шлёт заголовок Proxy: чей-то адрес, и обработчик видит у себя HTTP_PROXY со значением, которое пришло от постороннего человека. Библиотека внутри читает эту переменную и покорно уводит все исходящие запросы через чужую машину.

Поэтому curl и часть библиотек перестали доверять заглавному HTTP_PROXY. Строчный http_proxy снаружи так не подделаешь, его выставляет только тот, кто запускает процесс.

Правила, которые работают везде:

  • http_proxy пишем строчными;
  • HTTPS_PROXY и https_proxy читаются оба, но держите единообразие и пишите строчными;
  • NO_PROXY и no_proxy тоже оба, регистр там ни на что не влияет;
  • в Windows регистр имён вообще не различается, поэтому вылезает всё это только на линуксовых машинах.
nastroyka_pro
nastroyka_pro
Ветеран
сообщений 2110
с мар
8 октября, 11:21#3
iron_shell: строчный http_proxy снаружи так не подделаешь

Вот теперь понятно, откуда такая кривизна. Думал, кто-то просто накосячил в разборе имён.

Настя Лужина
Настя Лужина
Новичок
сообщений 265
с янв, второй сезон
15 марта, 14:38#4

подождите, а если я в питоне пишу os.environ['HTTP_PROXY'] он найдёт переменную заданную строчными

byteflow
byteflow
Новичок
сообщений 225
с фев, второй сезон
22 августа, 17:55#5

Настя, нет. os.environ в линуксе различает регистр буквально, это обычный словарь по тому, что отдала система.

import os
print(os.environ.get("HTTP_PROXY"))   # None
print(os.environ.get("http_proxy"))   # http://10.0.0.5:8080

А вот requests внутри себя перебирает оба написания сам, поэтому сессия ходит правильно, даже если руками вы ничего не нашли. Отсюда и ваша картинка: curl молчит, питон работает.

Ринат Ахметов
Ринат Ахметов
Участник
сообщений 700
с авг
1 января, 08:12#6

Простой способ перестать гадать: посмотреть, что процесс реально видит, изнутри самого процесса.

что видит запущенный процесс
что видит запущенный процесс

Последняя строка отдельно: половина случаев «переменная есть, но не работает» это запуск через юнит или через cron с пустым окружением.

iron_shell
iron_shell
Знаток
сообщений 1050
с июн
8 июня, 11:29#7

Про cron подписываюсь. Там окружение урезано до пары переменных, и никакие профили оболочки не читаются.

nastroyka_pro
nastroyka_pro
Ветеран
сообщений 2110
с мар
15 ноября, 14:46#8

Свёл у себя всё к строчным именам и вынес их в один файл, который подтягивают и юнит, и оболочка.

/etc/sbor.env:
http_proxy=http://10.0.0.5:8080
https_proxy=http://10.0.0.5:8080
no_proxy=localhost,127.0.0.1,10.0.0.0/8

curl и питон теперь ведут себя одинаково. Отдельное спасибо за историю с заголовком, буду знать, откуда у этого ноги растут.