web-dev-qa-db-ja.com

Nginx変数$ Host、$ http_Host、および$ server_nameの違いは何ですか?

3つのNginx変数の違いは何ですか$Host$http_Host$server_name

どちらを使用すればよいかわからない書き換えルールがあります。

location = /vb/showthread.php {
    # /vb/showthread.php?50271-What-s-happening&p=846039
    if ($arg_p) {
        return 301 $scheme://$Host/forum/index.php?posts/$arg_p/;
        }

「リライトルールで___変数を使用する」だけでなく、それらの間の理論的な違いも説明する答えを探しています。

46
Jeff Widman

特に$Hostを使用する必要があります。これは、他の変数のいずれかのセマンティクスを特に必要としない限り、ユーザーエージェントの動作に関係なく、何かが実用的であることが保証されている唯一のものであるためです。

違いは nginxのドキュメント で説明されています:

  • $Hostには、「この優先順位で:要求行からのホスト名、または「Host」要求ヘッダーフィールドからのホスト名、または要求と一致するサーバー名」が含まれます。
  • $http_Hostには、HTTP "Host"ヘッダーフィールドのコンテンツが含まれます(リクエストに含まれていた場合)。
  • $server_nameには、nginx構成で定義された、要求を処理した仮想ホストのserver_nameが含まれています。 serverに複数のserver_namesが含まれている場合、最初の変数のみがこの変数に存在します。

ユーザーエージェントがホスト名をHost:ヘッダーではなくリクエスト行で送信することは合法であるため、プロキシに接続する場合を除いてほとんど行われませんが、これを考慮する必要があります。

また、ユーザーエージェントがホスト名をまったく送信しない場合も考慮する必要があります。古代のHTTP/1.0リクエストと最新の悪質なソフトウェア。複数のWebサイトにサービスを提供している場合、またはサーバーにWebサイトが1つしかない場合は、単一の仮想ホストを通じてすべてを処理する可能性がある場合、何も提供しないキャッチオール仮想ホストにそれらを迂回することによってそうすることができます。 。後者の場合、これも考慮する必要があります。

$Host変数のみが、HTTPリクエストを形成するときにユーザーエージェントが実行できるすべての可能なことを説明します。

56
Michael Hampton

私もしばらくこれに苦労しました。 $ http_XXXXXが宣言されたすべてのヘッダー変数を参照していることを理解したときに明らかになりました。

したがって、$ http_user_agent、$ http_refererは「USER AGENT」、「REFERER」は小文字とアンダースラッシュで参照されます。これは、多くのNGINX構成サンプルで$ http_upgradeがどこから来ているのかを説明しました。

https://stackoverflow.com/questions/15414810/whats-the-difference-of-Host-and-http-Host-in-nginx から読む

1
luison

受け入れられた回答に記載されていない別の重要なポイントを追加したいと思います。

$Host do [〜#〜] not [〜#〜]ポート番号を持っているが、$http_Hostはポート番号を含みます。

編集:常にではありません。

「add_header Y-blog-http_Host "$ http_Host" always;」というヘッダーを設定しました。

次にcurl -I -L domain.com:80(または443)で、ヘッダーにポート番号がまったく表示されません。 nginx-extra 1.10.3で検証済み。これは、一般的なhttp(s)ポートまたはnginx構成だからです。このコメントは、物事をしないと言うだけですalwaysは、あなたが思うように振る舞います。

1