goofys の --use-content-type オプションが限られた拡張子でしか有効にならない問題の解消方法


問題

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 があるか否かをチェックする癖をつけた方がよいかもしれない。