NginxでQuery Stringを判定して、Rewriteする

NginxでQuery Stringの値を判定し、rewriteさせるメモです。
nginx_img

やりたいこと

codeの値を判定して、301転送を振り分けしたい。
Query Stringのcodeの値がユニークで別のものになっているので、正規表現は使えない。
http://example.jp/aaaaa?code=b1111 ⇒301転送 http://example.jp/aaaaa?code=centos
http://example.jp/aaaaa?code=b2222 ⇒301転送 http://example.jp/aaaaa?code=ubuntu
http://example.jp/aaaaa?code=b3333 ⇒301転送 http://example.jp/aaaaa?code=debian
http://example.jp/aaaaa?code=b4444 ⇒301転送 http://example.jp/aaaaa?code=redhat
http://example.jp/zzzzz?code=b1111 ⇒301転送 http://example2.jp/zzzzz?code=centos
http://example.jp/zzzzz?code=b2222 ⇒301転送 http://example2.jp/zzzzz?code=ubuntu
http://example.jp/zzzzz?code=b3333 ⇒301転送 http://example2.jp/zzzzz?code=debian
http://example.jp/zzzzz?code=b4444 ⇒301転送 http://example2.jp/zzzzz?code=redhat
:
:
100件以上。

設定方法

最初はこんな感じで、やればいいんでしょ。っと思ってましたが、全然NGでした。

rewrite /aaaaa?code=b1111$ http://example.jp/aaaaa?code=centos permanent;
rewrite /aaaaa?code=b2222$ http://example.jp/aaaaa?code=ubuntu permanent;
rewrite /aaaaa?code=b3333$ http://example.jp/aaaaa?code=debian permanent;
rewrite /aaaaa?code=b4444$ http://example.jp/aaaaa?code=redhat permanent;
                :
                :

とりあえず、以下で想定通りの動きは確認できました。

set $keyword_name "";

if ($args ~ "code=(.*)") {
    set $keyword_name $1;
}
if ($keyword_name = "b1111") {
    rewrite ^/aaaaa.*$ http://example.jp/aaaaa?code=centos? permanent;
    rewrite ^/zzzzz.*$ http://example2.jp/zzzzz?code=centos? permanent;
    break;
}
if ($keyword_name = "b2222") {
    rewrite ^/aaaaa.*$ http://example.jp/aaaaa?code=ubuntu? permanent;
    rewrite ^/zzzzz.*$ http://example2.jp/zzzzz?code=ubuntu? permanent;
    break;
}
if ($keyword_name = "b3333") {
    rewrite ^/aaaaa.*$ http://example.jp/aaaaa?code=debian? permanent;
    rewrite ^/zzzzz.*$ http://example2.jp/zzzzz?code=debian? permanent;
    break;
}
if ($keyword_name = "b4444") {
    rewrite ^/aaaaa.*$ http://example.jp/aaaaa?code=redhat? permanent;
    rewrite ^/zzzzz.*$ http://example2.jp/zzzzz?code=redhat? permanent;
    break;
}
                :
                :

※最初に変数を宣言して初期化しておくこと。

set $keyword_name "";

最初に宣言しておかないと、「using uninitialized “keyword_name” variable」というエラーが発生します。リダイレクトの動作は正常に動くので、しばらく気付きませんでした。。。

注意点

転送先の最後に?を付けないと・・・

NginxはQuery Stringを自動で引き継いで設定するようです。
転送先の最後に?を付けることで、転送先にQuery Stringを引き継がせないようにしています。

if ($args ~ "code=(.*)") {
    set $keyword_name $1;
}
if ($keyword_name = "b1111") {
    rewrite ^/aaaaa.*$ http://example.jp/aaaaa?code=centos permanent;
                                ↑ここの?を取った。
    break;
}

上記の設定だと、以下のように、最後尾に &code=b1111 が付いてきてしまいます。
http://example.jp/aaaaa?code=b1111 ⇒301転送 http://example.jp/aaaaa?code=centos&code=b1111

転送先の最後に?を付けた場合
http://example.jp/aaaaa?code=b1111 ⇒301転送 http://example.jp/aaaaa?code=centos

本記事は、Qiitaで過去投稿しています。
http://qiita.com/arai/items/1e411759b6d64614f4f6