web-dev-qa-db-ja.com

nginx:書き換えられたロケーションブロックにカスタムヘッダーを指定します

Nginxの特定のlocationブロックにのみいくつかのヘッダーを設定しようとしています。

私が抱えている問題は、それらのlocationブロックにrewriteステートメントが含まれていることです。これは、カスタムヘッダーを削除しているようです。

この例では、次の2つのルールが必要です。

  • _/static_内のファイルには、_expires max;_(ヘッダー_Cache-Control: max-age=some huge value_および_Expires: some future date really far off_を設定)があり、名前が_/static_を含まないものに書き換えられている必要があります。
  • 他のすべてのファイルには_Cache-Control: public_が必要です(_max-age_はありません)

これが私が試した構成です:

_server {
    listen [::]:80;
    root /somepath;
    location /static {
        expires max;
        rewrite /static(.*) /whatever$1;
    }
    add_header Cache-Control public;
}
_

そして、次のディレクトリ構造を持っています:

_/somepath
/somepath/f1.txt
/somepath/static/f2.txt
_

次に、次のようになります。

  • _f1.txt_:_Cache-Control: public_、Expiresヘッダーなし
  • _f2.txt_:_Cache-Control: public_、Expiresヘッダーなし

これは_f1.txt_には有効ですが、_f2.txt_には有効ではありません。私はそれをこのようにしたい:

  • _f1.txt_:_Cache-Control: public_、Expiresヘッダーなし
  • _f2.txt_:_Cache-Control: max-age=some huge value_、_Expires: some future date really far off_

この問題は、rewrite /static(.*) /whatever$1;行に起因していると思います。これにより、nginxはこれまでに追加したヘッダーをキャンセルしてから、再度追加します(したがって、_Cache-Control_を再度追加します)。そのため、簡単な回避策は次のようになります。

_server {
    listen [::]:80;
    root /somepath;
    location /static {
        rewrite /static(.*) /whatever$1;
    }
    location /whatever {
        expires max;
    }
    add_header Cache-Control public;
}
_

問題は、私の実際の設定ファイルでは、rewriteがそれほど見栄えが良くないことです。書き直されたURLは簡単には一致しません _expires max_を持つべきではないいくつかのファイルとも一致しない方法であるため、この回避策を実際に使用することはできません。

それらのヘッダーをrewriteの後に固定する方法はありますか?

[〜#〜] edit [〜#〜]:実際のURLは次のようになります。

_location ~ /(?:posts-)?img/.*-res- {
    access_log               off;
    expires                  max;
    rewrite                  "/img/(.*)-res-.{8}(.*)" /img/$1$2;
    rewrite                  "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2;
}
_

_/img_にlocationブロックを追加して、最初のrewriteルールを使用して書き換えられたファイルを処理することはできますが、2番目のルール(_/posts_)に追加することはできません。 )_/posts_内の一部のファイルはキャッシュ可能なリソースではないため、_expires max_を含めるべきではありません。

編集2:完全な構成(または少なくともすべての関連部分を含む):

_server {
    listen [::]:80;
    root /somepath;
    server_name domain.tld;
    location ~ /(?:posts-)?img/.*-res- {
        access_log               off;
        expires                  max;
        rewrite                  "/img/(.*)-res-.{8}(.*)" /img/$1$2;
        rewrite                  "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2;
    }
    add_header Cache-Control public;
}
_

ディレクトリ構造:

_/somepath
/somepath/img/f1.png
/somepath/posts/post1.html
/somepath/posts/d1/f2.png
/somepath/posts/d2/f2.png
_

HTTPリクエストに応じて予想される動作:

  • _GET /somepath_:_/somepath_と_Cache-Control: public_を提供します
  • _GET /somepath/img/f1.png_:_/somepath/img/f1.png_と_Cache-Control: public_を提供します
  • _GET /somepath/img/f1-res-whatever.png_:_/somepath/img/f1.png_によって送信されたヘッダーとともに_expires max_を提供します
  • _GET /somepath/posts/post1.html_:_/somepath/posts/post1.html_と_Cache-Control: public_を提供します
  • _GET /somepath/posts/d1/f2.png_:_/somepath/posts/d1/f2.png_と_Cache-Control: public_を提供します
  • _GET /somepath/posts-img/d1/f2-res-whatever.png_:_/somepath/posts/d1/f2.png_によって送信されたヘッダーとともに_expires max_を提供します
5
Etienne Perot

これは機能するはずです(ただし、これはやや単純な構成で検証しました)。ちなみに、Igor Sysoevは、正規表現の場所をできるだけ使用しないことをお勧めします。

    location /img {
        if ($arg_max) { expires max; }
        ...
    }

    location /posts-img {
        if ($arg_max) { expires max; }
        ...
    }

    location ~ /(?:posts-)?img/.*-res- {
        access_log               off;
        expires                  max;
        rewrite                  "/img/(.*)-res-.{8}(.*)" /img/$1$2?max=1;
        rewrite                  "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2?max=1;
    }
2
sendmoreinfo

大文字と小文字を区別しない場合 ロケーションマッチング

location ~* /static/

大文字と小文字を区別しない場合は、「*****」を削除してください

location ~* /static/

ソースNginxロケーションディレクティブ ドキュメント

0
Sameer