Go 语言检测一个文件的类型 http.DetectContentType

yufei       5 年, 6 月 前       9986

做 Web 应用程序时,经常需要对用户上传的文件类型做一下检查,比如判断上传的是否是 pnggifjpg 等图片类型,还是 pdf。并针对不同的类型做一些处理,比如在需要图片的场合,如果上传的文件类型为非图片,那么就要拒绝并告诉用户需要一张图片。

这种需求,往往我们都是通过上传的文件的扩展名来判断,比如如果以 .jpg 结尾,那么我们可能就认为是 jpg 图片。

但这种判断方式往往存在一个隐患,就是恶意用户可能会把一些恶意程序简单的以 .jpg 结尾来骗过我们的逻辑。在这种情况下,最好的方式就是根据上传内容的前几个字节来判断。

根据上传的内容来判断上传的内容类型,一般情况前三个字节或者前八个自己就可以了。比如 PNG 格式的图片,以十六进制 89504E47 开头

http.DetectContentType() 方法

Go 语言的 net/http 包下的方法 http.DetectContentType() 就是使用了刚刚我们提到的前几个字节判断文件类型的方式。

http.DetectContentType() 方法会读取内容的前 512 个字节的内容,并根据它们判断文件的类型,然后返回该文件的 MIME 类型。如果是未知类型,则会返回 application/octet-stream

其实一般情况下用不了 512 个字节,顶多使用前 32 个字节。

我们写一个范例,使用 http.DetectContentType() 返回文件的 MINE 类型

package main

import (
    "os"
    "fmt"
    "net/http"
)

func main() {

    // Open File
    f, err := os.Open("test.pdf")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    // Get the content
    contentType, err := GetFileContentType(f)
    if err != nil {
        panic(err)
    }

    fmt.Println("Content Type: " + contentType)
}

func GetFileContentType(out *os.File) (string, error) {

    // 只需要前 512 个字节就可以了
    buffer := make([]byte, 512)

    _, err := out.Read(buffer)
    if err != nil {
        return "", err
    }

    contentType := http.DetectContentType(buffer)

    return contentType, nil
}
目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.