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タイプが判別できるかはソースコード内の以下の箇所に定義されています。
// 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判別
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などの利用を検討する必要がありそうです。
この記事を書いた人
- 創造性を最大限に発揮するとともに、インターネットに代表されるITを活用し、みんなの生活が便利で、豊かで、楽しいものになるようなサービスやコンテンツを考え、創り出し提供しています。
この執筆者の最新記事
RECOMMENDED
関連記事
NEW POSTS
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー