简体   繁体   English

如何检查通过多部分表单发布的文件是否为图像类型,并且它是否小于Go中给定的maxsize?

[英]How can I check if a posted file via multipart form is of image type and that it is less than a given maxsize in Go?

I would like to know if there is a way of checking the size and the type before uploading it to the server. 我想知道在将其上传到服务器之前是否有办法检查大小和类型。 I am worried about people trying to upload really large files to slow the server down on purpose. 我担心有人试图上传真正大的文件以减慢服务器故障。

I only know how to check the size of a file after I have copied it to the server. 我只知道在将文件复制到服务器后如何检查文件的大小。 I don't know how to check the file type. 我不知道如何检查文件类型。 I would like to do it before having to upload 2 GB of data, and then validating the file. 我想在上传2 GB数据然后验证文件之前这样做。

This is what I have so far but this copies the file to the server first which is not what I want. 这是我到目前为止,但这首先将文件复制到服务器,这不是我想要的。

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
}

To avoid having tons of data uploaded to your server, I recommend wrapping your multipart.File , which is essentially an io.Reader with an io.LimitedReader , like 为了避免将大量数据上传到您的服务器,我建议包装multipart.File ,它本质上是一个io.Readerio.LimitedReader ,如

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

and then work on the wrapped reader. 然后在wrapped读者上工作。 This will read the specified amount of bytes and then return EOF, so anything larger than 10 MiB will be truncated. 这将读取指定的字节数,然后返回EOF,因此大于10 MiB的任何内容都将被截断。

To check whether the received data is an image, you have two choices: 要检查收到的数据是否为图像,您有两种选择:

  1. Parse the data with image.Decode(io.Reader) , that will throw an error if it can't parse the data as an image - this also allows you to check whether the received data is complete and correct. 使用image.Decode(io.Reader)解析数据,如果它无法将数据解析为图像,则会抛出错误 - 这也允许您检查接收的数据是否完整和正确。 Note however that this takes some time/steals performance. 但请注意,这需要一些时间/窃取性能。 Maybe you want to avoid this, if you just discard the decoded image afterwards. 如果你之后丢弃解码后的图像,也许你想避免这种情况。 Be sure to check the godoc for the image package, as you will have to import any formats you expect to decode. 请务必检查图像包的godoc ,因为您必须导入您希望解码的任何格式。
  2. Check the magic number , PNG files for example have 89 50 4e 47 0d 0a 1a 0a as their magic number. 检查幻数 ,PNG文件例如有89 50 4e 47 0d 0a 1a 0a作为他们的幻数。 However, a correct magic number does not imply a correct image. 但是,正确的幻数并不意味着正确的图像。 Especially if you truncated larger images to 10 MiB. 特别是如果您将较大的图像截断为10 MiB。

If you have the power needed to decode every image at hand, go for it - the results should be more precise, but this is just a recommendation. 如果你有解码每个图像所需的功率,那就去吧 - 结果应该更精确,但这只是一个建议。

I would rather not check the FileHeader (pkg/mime/multipart/#FileHeader) for the file type, I expect it to be unreliable. 我宁愿不检查文件类型的FileHeader(pkg / mime / multipart /#FileHeader),我希望它不可靠。 You might, however, find information about the (original) file size in there, I recommend just dumping the FileHeaders for some requests. 但是,您可能会在那里找到有关(原始)文件大小的信息,我建议只为某些请求转储FileHeaders。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Go中接收具有多部分/表单数据边界的POSTed参数 - How to receive POSTed parameter with multipart/form-data boundary in Go Go - 如何检查类型是否相等? - Go - How can I check for type equality? 如何使用 go 的 net/http 或类似替代方法保存在 multipart/form-data POST 请求中收到的文件? - How can I save the file received in a multipart/form-data POST request using go's net/http or similar alternative? 如何在go中获取多部分格式文件的文件名? - how to get file name of multipart-form file in go? 如何组织此Go代码,从嵌入式类型重新定义方法,以减少冗余和更易维护? - How can I organise this Go code that redefines methods from an embedded type to be less redundant and more maintainable? 我可以用 Content-Type: multipart/form-data 发帖吗 - Can I post with Content-Type: multipart/form-data 在Go中给定名称的情况下,如何猜测文件的类型和编码? - How to guess the type and encoding of a file given it's name in Go? 如何使用官方 go-driver 在 MongoDB 中持久化文件(远小于 16MB) - How to persist a file (much less than 16MB) in MongoDB using official go-driver 如何发布多部分图像而不保存在磁盘上? - How can I post multipart image without to save on disk? 如何在Go中引用接口类型? - How can I refer to an interface type in Go?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM