Azure App Service on LinuxによるWebサーバで、比較的新しい、あるいは珍しい種類のファイルのダウンロード/表示に失敗する場合、対応する「MIMEタイプ」が設定されていない可能性がある。このような場合、内蔵の「NGINX」でMIMEタイプを追加/変更すればよい。その方法を紹介する。
対象:Azure App Service on Linux
あまり使われることのない種類のファイルをWebサーバに配置した際、クライアント側で正しくダウンロードできなかった……。そのような経験や報告を受けたことはないだろうか?
その原因の一つとして、対象ファイルに対応する「MIMEタイプ」がWebサーバ側に設定されていないことが挙げられる。ただ、筆者が確認した限りでは、Azureの「App Service on Linux」でMIMEタイプをGUIから簡単に設定する機能はないようだ。
そこで本Tech TIPSでは、Webサーバの構築/運用担当者を対象として、Azure App Service on Linux内蔵のWebサーバ「NGINX」の設定を変更することで、MIMEタイプを追加したり変更したりする方法を紹介する。
App Service内蔵のNGINXの設定変更については、「【Azure】App ServiceのWebサーバ『NGINX』をカスタマイズする方法」を前提としているので、以下を読み進める前に参照していただきたい。また、「【Azure】App Service on LinuxでディレクトリごとにクライアントIP制限を実装する方法と注意点」も参考になるだろう。
Azure App Service on Linuxの場合、NGINXのMIMEタイプの設定は[/etc/nginx/mime.types]というファイルに集約されている。
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
<中略>
video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/ogg ogv;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-matroska mkv;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}
「types」はMIMEタイプを定義するためのディレクティブで、ブロック内に「<MIMEタイプ> <拡張子1> <拡張子2> ……;」のように記述する。
App Service on Linuxでは、上記のようにtypesディレクティブが記述されたファイルが[/etc/nginx/nginx.conf]のhttpコンテキスト内でインクルードされ、下位のserverコンテキストにも継承されるようになっている。
独自のMIMEタイプを追加したり、既存のMIMEタイプを変更したりするには、前述の[/etc/nginx/mime.types]ファイルを修正版の設定ファイルと差し替えるのが手っ取り早い。
ここでは、差し替える設定ファイルとして[/home/custom/etc/nginx/mime.types]を新規作成し、以下のように[/etc/nginx/mime.types]の内容を複製しつつ、MIMEタイプの追加/変更をする。[/home/custom/]というディレクトリの扱い方については、Tech TIPS「【Azure】App ServiceのWebサーバ『NGINX』をカスタマイズする方法」を参照していただきたい。
# mime.types: MIMEタイプを定義する設定ファイル。[/etc/nginx/mime.types]を差し替える
types {
# AndroidアプリのパッケージファイルのMIMEタイプを追加
application/vnd.android.package-archive apk;
# 以下、元の[/etc/nginx/mime.types]のtypesディレクティブのブロック内を複製(一部は修正)
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
# 元々のJavaScriptのMIMEタイプをコメントアウトしつつ……
#application/javascript js;
# 別のMIMEタイプへ変更
text/javascript js;
application/atom+xml atom;
application/rss+xml rss;
<中略>
video/x-ms-wmv wmv;
video/x-msvideo avi;
}
上記リストでは、拡張子が[.apk]であるAndroidスマートフォンのアプリケーションパッケージファイルのMIMEタイプを追加している。またJavaScriptファイル(拡張子は[.js])のMIMEタイプを「application/javascript」から「text/javascript」へ変更した。
修正版設定ファイルが用意できたら、シンボリックリンクで元の[/etc/nginx/mime.types]と差し替える(以下、詳細は前出のTech TIPSを参照していただきたい)。
ln -snf /home/custom/etc/nginx/mime.types /etc/nginx/mime.types
動作確認をするには、設定ファイルを検証してエラーがなければNGINXを再ロードする。
nginx -t && nginx -s reload
クライアントで対象ファイルのダウンロードあるいは表示などに成功したら、スタートアップスクリプトの[/home/startup.sh]に前述のシンボリックリンクのコマンドラインを追記すればよい。
MIMEタイプを定義するtypesディレクティブは、server/locationコンテキスト内でも指定できる。
例えば、あるディレクトリだけで前述の.apkファイルをダウンロードできるようにするには、以下のようなlocationコンテキストをサイト設定ファイルの[/home/custom/etc/nginx/sites-available/default]内に挿入する。
# sites-available/default: サイトの設定ファイル。[/etc/nginx/sites-available/default]を差し替える
server {
<前略>
# ----- 以下を挿入 -----
# .apkファイルのダウンロード専用フォルダ
location ~ ^/auth/download/apppkg/ {
type {
# AndroidアプリのパッケージファイルのMIMEタイプを追加
application/vnd.android.package-archive apk;
}
}
# -----挿入終わり -----
<後略>
}
ただし、上記リストのように記述すると、対象ディレクトリ以下には[mime.types]ファイルで定義しているMIMEタイプが全く反映されなくなる(継承する方法はないようだ)。そのため、MIMEタイプが定義されている.apkファイル以外がリクエストされると、そのレスポンスの「Content-Type」ヘッダの値には必ず「application/octet-stream」というデフォルトのMIMEタイプが適用されてしまう。当然、各ファイルは正しく利用できなくなる。
これを防ぐには、locationコンテキスト内のtypesディレクティブに、使用する(予定のある)全MIMEタイプの定義を記述する必要がある。しかし、それだと[mime.types]ファイルと重複する記述が増えてしまい、後々の管理やメンテナンスの手間が増えてしまう。
それならばlocationコンテキストでの記述、すなわち特定のディレクトリだけでMIMEタイプを追加/変更するのは止めて、前述した[mime.types]ファイルだけを修正してサイト全体に反映する方が面倒は少ない、というのが筆者の率直な感想だ。
[mime.types]ファイルのMIMEタイプを修正する場合、他の設定ファイルとの間で矛盾が生じないように気を付ける必要がある。
具体例としては、Tech TIPS「【Azure】App Service on Linuxで応答時のコンテンツ圧縮をカスタマイズして性能を高める(NGINX編)」で説明しているGZIP圧縮が挙げられる。
圧縮対象のファイルの種類を増やすには、「gzip_types」ディレクティブのパラメーターに対象ファイルのMIMEタイプを列挙する必要がある。その際、いずれのMIMEタイプも[mime.types]ファイルのtypesディレクティブで定義されていなければならない。MIMEタイプが食い違っていると、もちろん対象ファイルが正しく圧縮されないので注意しよう。
App Service on Linuxの場合、[mime.types]ファイルのtypesディレクティブで定義されていない種類のファイルについては、「application/octet-stream」というデフォルトのMIMEタイプが適用される。
これを変更するには、以下のように「default_type」ディレクティブを利用する。
default_type <デフォルトのMIMEタイプ>;
サイト全体に反映するなら[sites-available/default]ファイルのserverコンテキスト内にこのディレクティブを記述する。特定のディレクトリだけに反映するなら同ファイルにlocationコンテキストを挿入して、そこに記述すればよいだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.