goでデータ形式を識別するためのMIMEタイプを判定する方法
業務でアップロードされた画像ファイルのMIMEタイプを判別する必要があったので調査しました。
httpパッケージのDetectContentType
調べてみるとgoのhttpパッケージにDetectContentTypeという関数がありました。
func DetectContentType
func DetectContentType(data []byte) string
説明
DetectContentType implements the algorithm described at https://mimesniff.spec. whatwg.org/ to determine the Content-Type of the given data. It considers at most the first 512 bytes of data.
DetectContentType always returns a valid MIME type: if it cannot determine a more specific one, it returns “application/octet-stream”.
DetectContentType always returns a valid MIME type: if it cannot determine a more specific one, it returns “application/octet-stream”.
以下翻訳
DetectContentTypeは、https://mimesniff.spec.whatwg.org/ で説明されているアルゴリズムを 実装し、与えられたデータのContent-Typeを決定します。 データの最初の 512 バイトまでを考慮します。
DetectContentTypeは、常に有効なMIMEタイプを返します。より具体的なMIMEタイプを決定できない場合は、”application/octet-stream “を返します。
DetectContentTypeは、常に有効なMIMEタイプを返します。より具体的なMIMEタイプを決定できない場合は、”application/octet-stream “を返します。
実際のソースコードはここで確認できます。
実際にどのMIMEタイプが判別できるかはソースコード内の以下の箇所に定義されています。
1 2 3 |
// Data matching the table in section 6. var sniffSignatures = []sniffSig{ ・・・ |
ざっと見てみると以下のMIMEが判別できるようです。
- “text/html; charset=utf-8”
- “text/plain; charset=utf-8”
- “text/xml; charset=utf-8”
- “text/plain; charset=utf-16be”
- “text/plain; charset=utf-16le”
- “text/plain; charset=utf-8”
- “image/x-icon”
- “image/x-icon”
- “image/bmp”
- “image/gif”
- “image/webp”
- “image/png”
- “image/jpeg”
- “audio/basic”
- “audio/aiff”
- “audio/mpeg”
- “application/ogg”
- “audio/midi”
- “audio/wave”
- “video/avi”
- “video/mp4”
- “video/webm”
- “font/ttf”
- “font/otf”
- “font/collection”
- “font/woff”
- “font/woff2”
- “application/pdf”
- “application/postscript”
- “application/x-gzip”
- “application/zip”
- “application/x-rar-compressed”
- “application/x-rar-compressed”
- “application/wasm”
- “application/vnd.ms-fontobject”
- “application/octet-stream”
動作のサンプル
ファイルを読み込んでMIME判別
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package main import ( "fmt" "log" "net/http" "os" ) func main() { bytes, err := os.ReadFile("./image.jpg") if err != nil { log.Fatal(err) } mimeType := http.DetectContentType(bytes) fmt.Println(mimeType) // image/jpeg が出力される } |
さいごに
いかがだったでしょうか。標準パッケージに入っている関数なので気軽に使えて便利ですね。 ただ、アップロードされるファイルの形式はこれ以外にも沢山あります。 たとえばMicrosoftOfficeのファイルなどはDetectContentTypeでは正確に判別できません。 試しにxlsxファイルで実行したところ、「application/zip」と判別されてしまいました。
今回は画像が対象だったのでこの関数で対応できますが、幅ひろいファイルタイプに適応させるには 別途mimetypeなどの利用を検討する必要がありそうです。
The following two tabs change content below.

竹内 和也
事業開発部 web application engineer
大学卒業後、Web系ベンチャー企業でシステムエンジニアを経て、2009年にアーティスへ入社。
システムエンジニアとして多くの大学・病院・企業・自社のwebシステム開発に携わる。
2020年より事業開発部として新規サービスの開発に従事している。
資格:LPIC3

最新記事 by 竹内 和也 (全て見る)
- Go WebAssemblyでブラウザ上でGoを実行する その2 Go側からJavascriptを操作する - 2022年6月21日
- GoのコードをWebAssenblyにコンパイルしてブラウザ上でGoを実行する - 2022年4月25日
- 【Go】go.modのreplaceでローカルのモジュールを参照する - 2022年2月22日
- goでHTTPリクエストボディのサイズを制限する「MaxBytesReader」 - 2021年12月15日
- 【Go言語】jsonデータをstreamで扱うEncoder、Decoder型を試してみる - 2021年10月17日
RECOMMENDED
関連記事
NEW POSTS
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー