如何在 Golang 中检测额外的 mime 类型

How to detect additional mime type in Golang

net/http 包中有 http.DetectContentType([]byte) 函数。但仅支持有限数量的类型。如何添加 docxdocxlsxlsxpptppsodt、[=19] 的支持=], odp 文件不是按扩展名,而是按内容。 据我所知,存在一些问题,因为 docx/xlsx/pptx/odp/odt 文件与 zip 文件 (50 4B 03 04).

x结尾的文件比较容易检测。只需解压缩并阅读 .rels/_rels 文件。它包含文档中主文件的路径。它由命名空间 http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument 表示。只需检查它的名称。 docx 为 document.xml,xlsx 为 workbook.xml,pptx 为 presentation.xml

可在此处找到更多信息 ECMA-376

二进制格式更难检测。基本上你需要阅读 MS-CFB 文件系统并检查条目:

  • WordDocument 文档
  • WorkbookBook xls
  • PowerPoint Document for ppt
  • EncryptedPackage表示文件已加密。

目前无法扩展 http.DetectContentType,因为它使用固定的、未导出的 "sniffers" 切片:https://golang.org/src/net/http/sniff.gosniffSignatures 在撰写本文时位于第 49 行).

此外,我快速浏览了 godoc.org 以寻找更好的包,但没有找到任何您需要的可扩展和面向内容的包。

我的建议是:在 Go 的内容嗅探器实现(遵循 https://mimesniff.spec.whatwg.org/)的指导下构建您自己的包。

编辑:如果您愿意使用 CGO 并且使用的是 nix,则可以使用 libmagic 绑定,例如 https://github.com/jteeuwen/magic.

我发现 mimemagic, which I find preferable to magicmime 因为它不使用 cgo。但是 magicmime 更擅长区分 application/zip 和 office 文件类型。

免责声明:我是 mimetype.

的作者

对于三年后遇到同样问题的人,现在基于内容的 mime 类型检测包如下:

  • filetype

    • 纯 go,没有 c 绑定
    • 可以扩展以检测新的 MIME 类型
    • 对于以不止一种 MIME 类型传递的文件(例如:xlsx 和 docx 作为 zip 传递)存在问题,因为它在映射中存储匹配函数,因此它不能保证遍历的顺序
    • 检测到的 mime 类型数量有限
  • magicmime

    • 需要安装 libmagic-dev
    • 在这 3 个中,它检测到的 MIME 类型数量最多
    • 可以扩展,尽管更难...man magic
    • libmagic 不是线程安全的
  • mimetype

    • 纯 go,没有 c 绑定
    • 检测到的 MIME 类型数量多于 filetype
    • 线程安全
    • 可以延长