nginxのtry_filesを使って返却するファイルやファイルパスを割り込ませる

どういうタイトルにするのが適切なのだろうか。イマイチ思いつかなかったのでこんな感じだけど、図にすると、こういうことをしたいとき。

https://www.flickr.com/photos/29619730@N06/4066833638/

実はこれ、8年程前に同じ事を考えていたんだけど、当時はnginxの存在を知らず、当時使っていたApacheでこのような方法を採れるのかどうかすら、このとき結局分からなかった。


最近はnginxをウェブサーバとして使うことが多いのだけど、そういえば、「当時考えていたこれ、nginxのtry_files使えばできるよね?」というのを思い立って、やってみた。



ここでは、上記の画像となるべく同じ構造にして設定を記述していく。

/var/www/dir_a/public_html 以下には下記のファイルが置いてある。
  • A.html
  • B.html
また、/var/www/dir_b/public_html 以下にも下記の様なファイルが置いてある。
  • A.html
  • C.html

このとき、DocumentRoot/var/www/dir_b/public_html であった場合、通常、下記のリクエストはそれぞれこのようになるはずである。

curl -I http://www.example.co.jp/A.html
-> HTTP/1.1 200 OK

curl -I http://www.example.co.jp/B.html
-> HTTP/1.1 404 Not Found

curl -I http://www.example.co.jp/C.html
-> HTTP/1.1 200 OK

curl -I http://www.example.co.jp/D.html
-> HTTP/1.1 404 Not Found


これをnginxで、下記の様な設定を行うと、上記の図の様な挙動にできる。




curl -I http://www.example.co.jp/A.html
-> HTTP/1.1 200 OK

curl -I http://www.example.co.jp/B.html
-> HTTP/1.1 200 OK

curl -I http://www.example.co.jp/C.html
-> HTTP/1.1 200 OK

curl -I http://www.example.co.jp/D.html
-> HTTP/1.1 404 Not Found


ただし、 http://www.example.co.jp/A.html でのリクエストで返ってきているのは /var/www/dir_b/public_html/A.html ではなくて、 /var/www/dir_a/public_html/A.html の方となる。
これでA.htmlへのGETリクエストに対して /var/www/dir_a/public_html にあるファイルを割り込ませられる。

B.htmldir_b にはないけど、 dir_a には存在するのそれが返却される。
逆に C.htmldir_a にはないけど、 dir_b にフォールバックしたときに存在を確認できるためこちらも C.html は 200ステータスで返却される。
D.html はどちらにもファイルが存在しないので、そのまま 404 エラーとなる。

この方法によって何が得になるかというと、運用上の都合などで、何らか画像やファイルを所定の場所とは別の所にアップロードして割り込ませることで、サイトの挙動を変更したい、というような使い方ができる。
逆の考えで、dir_aの方にファイルがなければ dir_b の方にフォールバックする、という指定ができる。
8年前の当時は何で必要だと思ったのか忘れてしまったけど。


ちなみに、 try_files の部分で、ファイルがなかったら 404 を返却したい。という意味で
try_files $uri $uri/ @dirB =404; 
と記述すると、@dirB を見に行ってくれず、@dirBにフォールバックする前に ファイルが存在しない 404 エラーで終了となってしまうので注意。(ここにチョットハマりました)

最近作ったアプリの話

先日、コナミ社の提供している コナステ のダウンロードコンテンツゲームを1クリックで起動できるアプリを作り、公開した。 Ks Game Launcher  ( Github ) 作った理由として、インストール時に作成されたショートカットをクリックするとブラウザが起動し、ログインし...