go - 如何检查通过多部分形式发布的文件是否为图像类型并且小于 Go 中给定的最大大小?

标签 go

我想知道是否有办法在上传到服务器之前检查大小和类型。我担心有人会故意上传非常大的文件来降低服务器速度。

我只知道将文件复制到服务器后如何检查文件的大小。我不知道如何检查文件类型。我想在上传 2 GB 数据之前执行此操作,然后验证文件。

这是我目前所拥有的,但是这首先将文件复制到服务器,这不是我想要的。

func userUploadImage(w http.ResponseWriter, r *http.Request, _ httprouter.Params) error {
    mpf, mpfh, err := r.FormFile("file")
    if err != nil {
        return nil
    }
    defer mpf.Close()

    dstFile, err := os.Create(config.UploadDir + "/img/" + mpfh.Filename)
    if err != nil {
        return err
    }
    defer dstFile.Close()

    size, err := io.Copy(dstFile, mpf)
    if err != nil {
        return err
    }

    spew.Dump(size)
    return nil
}

最佳答案

为了避免将大量数据上传到您的服务器,我建议包装您的 multipart.File,它本质上是一个带有 io 的 io.Reader。 LimitedReader,喜欢

wrapped := io.LimitReader(mpf,10*1024*1024)    //10 MiB

然后在 wrapped 阅读器上工作。这将读取指定数量的字节,然后返回 EOF,因此大于 10 MiB 的任何内容都将被截断。

检查接收到的数据是否为图片,有两种选择:

  1. 使用image.Decode(io.Reader) 解析数据,如果不能将数据解析为图像,将抛出错误 - 这也允许您检查接收到的数据是否是完整和正确的。但是请注意,这需要一些时间/窃取性能。也许你想避免这种情况,如果你只是在之后丢弃解码图像。请务必检查 godoc对于图像包,因为您必须导入您希望解码的任何格式。
  2. 检查 magic number , 例如 PNG 文件将 89 50 4e 47 0d 0a 1a 0a 作为它们的魔数(Magic Number)。然而,正确的魔数(Magic Number)并不意味着正确的图像。特别是当您将较大的图像截断为 10 MiB 时。

如果您有能力解码手头的每张图像,那就去做吧 - 结果应该更精确,但这只是一个建议。

我宁愿不检查 FileHeader (pkg/mime/multipart/#FileHeader) 的文件类型,我希望它不可靠。但是,您可能会在其中找到有关(原始)文件大小的信息,我建议只为某些请求转储 FileHeaders。

关于go - 如何检查通过多部分形式发布的文件是否为图像类型并且小于 Go 中给定的最大大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32560810/

相关文章:

rest - 如何在 Go 中编写通用处理程序?

具有不同(未知)字符串匹配的正则表达式

http - 使用基本身份验证和表单值进行 Http Post 请求

JSON 响应 : return nested JSON

go - 以匿名结构作为参数导出函数[不能在 package.Func 的参数中使用值(类型 struct {...})作为类型 struct {...}]

go - 设置go dep后依赖出现问题

go - "invalid character ' 1 ' after top-level value "解码 JSON

html - 使用 golang 的 DataTable 中的动态 URL

接口(interface)和将匿名字段嵌入到结构中

docker - 初始化 : true does not forward signals