nginxロケーションブロックはURLクエリ文字列と一致できますか?


23

nginx ブロックすることができlocationますはURLクエリ文字列と一致ますか?

たとえば、HTTP GET要求に一致する可能性のあるロケーションブロック

GET /git/sample-repository/info/refs?service=git-receive-pack HTTP/1.1

nginxは文字列の比較を行うだけなので、「location / git / sample-repository / info / refs?service = git-receive-pack」と推測します。
JosefScript

URL全体または疑問符(?)の前の部分のみの文字列比較?
デレクマハル



1
nginx.org/en/docs/http/request_processing.htmlには次のように明記されています。「すべてのタイプの場所は、引数なしでリクエスト行のURI部分のみをテストすることに注意してください。クエリ文字列のいくつかの方法で指定できます」
トーマスアーバン

回答:


37

nginxロケーションブロックはURLクエリ文字列と一致できますか?

短い答え:いいえ。

長い答え:このようなロケーションブロックが少数しかない場合は、回避策があります。

特定のクエリ文字列と一致する必要がある3つのロケーションブロックの回避策の例を次に示します。

server {
  #... common definitions such as server, root

  location / {
    error_page 418 = @queryone;
    error_page 419 = @querytwo;
    error_page 420 = @querythree;

    if ( $query_string = "service=git-receive-pack" ) { return 418; }
    if ( $args ~ "service=git-upload-pack" ) { return 419; }
    if ( $arg_somerandomfield = "somerandomvaluetomatch" ) { return 420; }

    # do the remaining stuff
    # ex: try_files $uri =404;

  }

  location @queryone {
    # do stuff when queryone matches
  }

  location @querytwo {
    # do stuff when querytwo matches
  }

  location @querythree {
    # do stuff when querythree matches
  }
}

$ query_string、$ args、または$ arg_fieldnameを使用できます。すべてが仕事をします。error_pageの詳細については、公式ドキュメントを参照してください

警告:標準のHTTPコードを使用しないようにしてください。


1
興味深いアプローチ!$args ~ "service=git-send-pack"代わりに推薦しても$args = "service=git-send-pack"いいですか?このフォームは、複数のクエリパラメータに対応しています。
デレク・マハール

1
stackoverflow.com/a/40313590/107158は、クエリ文字列引数を処理するために従ったアプローチを示しています。あなたの答えのように、私はifand $arg_fieldnameを使用しrewriteますがerror_page、andの代わりに使用しlocation @nameます。その例では@name置換パラメータに使用する私の試みrewriteが失敗したことに注意してください。
デレクマハル

1
ちなみに、それがあるべき$args ~$arg_somerandomfield =
デレク・マハール

1
mapこの目的でnginx 機能を使用することもできますが、これは高速です。
テロキルカネン

1
@PothiKalimuthu、これを明確にしてくれてありがとう。その間に私がやったことは、queryパラメータを次のようなURLパスに置き換えるfeedback/{auth_key}ことです/feedback?auth_key=abc。このようにして、使用する必要はありません。if使用regexして場所のパターンを定義できます。
WM

4

私はこの質問が1年以上前のものであることを知っていますが、ここ数日間、同様の問題で私の脳を破壊しました。プッシュとプルを含む、パブリックとプライベートのレポジトリに対して異なる認証と処理ルールが必要でした。これが私がついに思いついたものですので、私は共有したいと思いました。私ifはトリッキーなディレクティブを知っていますが、これは私にとってはうまくいくようです:

# pattern for all repos, public or private, followed by username and reponame
location ~ ^(?:\/(private))?\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?$ {

    # if this is a pull request
    if ( $arg_service = "git-upload-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /upload$uri;

    }

    # if this is a push request
    if ( $arg_service = "git-receive-pack" ) {

        # rewrite url with a prefix
        rewrite ^ /receive$uri;

    }

}

# for pulling public repos
location ~ ^\/upload(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing public repos
location ~ ^\/receive(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pulling private repos
location ~ ^\/upload\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}

# for pushing private repos
location ~ ^\/receive\/private(\/([A-Za-z0-9]+)\/([A-Za-z0-9]+)\.git(\/.*)?)$ {

    # auth_basic "git";
    # ^ if you want

    # ...
    # fastcgi_pass unix:/var/run/fcgiwrap.socket;
    # ...

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.