Вы должны почти всегда использовать его $host, так как гарантированно есть единственное, что имеет смысл, независимо от того, как ведет себя пользовательский агент, если только вам конкретно не нужна семантика одной из других переменных.
Разница объясняется в документации по nginx :
$host содержит «в таком порядке приоритета: имя хоста из строки запроса или имя хоста из поля заголовка запроса« Хост », или имя сервера, соответствующее запросу»
$http_host содержит содержимое поля заголовка HTTP «Host», если оно присутствовало в запросе
$server_nameсодержит server_nameвиртуальный хост, который обработал запрос, как это было определено в конфигурации nginx. Если a serverсодержит несколько server_names, в этой переменной будет присутствовать только первый.
Так как пользовательские агенты могут отправлять имя хоста в строке запроса, а не в заголовке Host:, хотя это делается редко, за исключением случаев подключения к прокси-серверам, вы должны учитывать это.
Вы также должны учитывать случай, когда пользовательский агент вообще не отправляет имя хоста, например, древние запросы HTTP / 1.0 и современное плохо написанное программное обеспечение. Вы можете сделать это, перенаправив их на универсальный виртуальный хост, который ничего не обслуживает, если вы обслуживаете несколько веб-сайтов или если у вас только один веб-сайт на вашем сервере, вы можете обрабатывать все через один виртуальный хост , В последнем случае вы должны это учитывать.
Только $hostпеременная учитывает все возможные действия, которые пользовательский агент может выполнять при формировании HTTP-запроса.
$schemeи$host...return 301 /forum/index.php?posts/$arg_p/;отлично работает.