[nginx]ホスト名に応じてレスポンスするファイルを振り分ける

nginx

nginx には ngx_http_map_module というハッシュテーブルを操作するモジュールがあり、リクエストヘッダーのホストやユーザーエージェントをキーと見立てて値を振り分けることができる。
このモジュールを使うと、複数のサブドメインをさばいていている時に、robots.txt のような各ドメインに必要なファイルをサブドメインに応じて振り分ける。

ngx_http_map_module の使い方

単純な例

まずは map を使った単純な例から

map $http_user_agent $mobile {
    default       0;
    "Opera Mini" 1;
}

これを Python っぽく置き換えると

mobile = dict()
mobile["Opera Mini"] = 1

というように key-value ペアをまず定義し、リクエスト処理時に

mobile.get(http_user_agent, 0) # default value is `0`

というようにリクエストヘッダーの http_user_agent をキーに値を取得する。

map の発展的な使い方

重複定義

map $http_user_agent $foo {
    default       0;
    "Opera Mini"  1;
}

map $http_user_agent $bar {
    default       "alpha";
    "dummy"       "beta";
}

というように、同じ変数($http_user_agent) に対して複数の map 変数($foo, $bar) を定義できる

Key-Valueをファイル管理

Key-Value のペアはファイル管理して include しても良い

map $http_user_agent $mobile {
  include /path/to/key-value.txt; # "Opera Mini" 1;
}

パターンマッチング

map の キーのパターンマッチングは

  • prefix match("*.example.com")
  • suffix match("mail.*")
  • 前方一致の正規表現(~^www\.(?P.*)$ $domain)

が使える

サブドメインで robots.txt を振り分ける

最後にもともとのきっかけとなったサブドメイン別 robots.txt の振り分けをやってみる。

設定

以下のような nginx.conf を用意

サブドメインによってマップ $robots_file のルールに従って robots.txt ファイルを振り分ける。

# dispatch robots.txt based on host request header
worker_processes  1;
daemon off;

events {
    worker_connections  1024;
}

http {
    root   html;

    # ngx_http_map_module http://nginx.org/en/docs/http/ngx_http_map_module.html
    map $http_host $robots_file {
        default           robots.txt;
        ~*web.example.com web-robots.txt;
        m.example.com     mobile-robots.txt;
    }

    server {
        listen       8000;
        server_name  *.example.com;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location = /robots.txt {
            try_files /$robots_file =404;
        }
    }
}

3 種類のサブドメイン分の robots.txt を用意。

~]$ echo 'default robots.txt' > html/robots.txt
~]$ echo 'robots.txt for mobile' > html/mobile-robots.txt
~]$ echo 'robots.txt for *web' > html/web-robots.txt

nginx を起動

~]$ ./objs/nginx  -c conf/nginx.conf

様々な host でアクセス

*web.example.com 系ドメインにアクセス

$ curl  http://localhost:8000/robots.txt -H host:dev-web.example.com
robots.txt for *web
$ curl  http://localhost:8000/robots.txt -H host:dev-web.example.com
robots.txt for *web

m.example.com ドメインにアクセス

$ curl  http://localhost:8000/robots.txt -H host:m.example.com
robots.txt for mobile

上記以外のドメインにアクセス

$ curl  http://localhost:8000/robots.txt -H host:example.com
default robots.txt
$ curl  http://localhost:8000/robots.txt -H host:www.example.com
default robots.txt

ということで、期待通りリクエストヘッダーの host で robots.txt ファイルを振り分けられている

References

Tagged with: ,
Posted in web

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 1 week ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 3 weeks ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 3 weeks ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 6 months ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 9 months ago
%d bloggers like this: