問題
Amazon Linux 2 上で goofys を使ってマウントした S3 バケットにファイルをアップロードし、これを直接ダウンロードさせる場合、 S3 オブジェクト保存時に指定された Content-Type 設定が利用される。
しかし、何のオプションも渡さずに goofys で S3 オブジェクトをマウントした場合、デフォルト値として binary/octet-stream
が利用されてしまい、予期せぬ挙動が起こることがある。 例えば PDF ファイルが binary/octet-stream 形式だと、ブラウザによっては別ページで開かずにダウンロードしてしまう。
これを解消するために、goofys の実行時に --use-content-type
オプションを利用することができる。 少し古いが、以下の記事を参照。
これを付けておけばOKと思っていたのだが、メジャーな拡張子、例えば .mp3
のファイルをアップロードした場合にContentTypeが識別されず、binary/octet-stream になってしまう状況に直面した(ただし、.jpg などの一部の拡張子は image/jpeg として設定されるなど、正常に識別される時もあった)。
この問題の解決方法を探る。
原因と解決策
このあたりを読めばわかるのだが、拡張子から ContentType を推論するのには /etc/mime.types
ファイルを利用している(先の DevelopersIO の記事にもちゃんと書いてある)。
しかし、記事執筆時点でレコメンドされる Amazon Linux 2 (amzn2-ami-hvm-2.0.20210525.0-x86_64-gp2, ap-northeast-1 の場合は ami-001f026eaf69770b4
) この辞書ファイルがデフォルトで入っていない。
$ ls /etc/mime.types
ls: cannot access /etc/mime.types: No such file or directory
なので、これを手動でインストールしてやる必要がある。
yum provides
で引いてみると、幸い、amzn2-core
にあるので、mailcap
をインストールした後にファイルをチェック。
$ sudo yum provides /etc/mime.types
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
mailcap-2.1.41-2.amzn2.noarch : Helper application and MIME type associations for file types
Repo : amzn2-core
Matched from:
Filename : /etc/mime.types
$ sudo yum -y install mailcap
(インストールの過程は略)
# コンテンツの中身を確認
$ head -n 30 /etc/mime.types
# This is a comment. I love comments. -*- indent-tabs-mode: t -*-
# This file controls what Internet media types are sent to the client for
# given file extension(s). Sending the correct media type to the client
# is important so they know how to handle the content of the file.
# Extra types can either be added here or by using an AddType directive
# in your config files. For more information about Internet media types,
# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
# registry is at <http://www.iana.org/assignments/media-types/>.
# IANA types
# MIME typeExtensions
application/1d-interleaved-parityfec
application/3gpp-ims+xml
application/activemessage
application/andrew-insetez
application/applefile
application/atom+xmlatom
application/atomcat+xmlatomcat
application/atomdeleted+xmlatomdeleted
application/atomicmail
application/atomsvc+xmlatomsvc
application/auth-policy+xmlapxml
application/batch-SMTP
application/beep+xml
application/calendar+xmlxcs
application/call-completion
application/cals-1840
application/ccmp+xmlccmp
これをインストールした後に goofys を再起動してファイルをマウントされたバケットに goofys 経由でコピーすれば、拡張子に応じた ContentType が S3 上のオブジェクトに反映されるようになった。
デフォルトで入っていないケースもあるようなので、 goofys 経由でファイルをアップロードする場合は、ちゃんと /etc/mime.types
があるか否かをチェックする癖をつけた方がよいかもしれない。