Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

Tags:

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.

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
}
like image 526
Aiden Avatar asked Feb 03 '26 03:02

Aiden


1 Answers

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

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

and then work on the wrapped reader. This will read the specified amount of bytes and then return EOF, so anything larger than 10 MiB will be truncated.

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. 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.
  2. Check the magic number, PNG files for example have 89 50 4e 47 0d 0a 1a 0a as their magic number. However, a correct magic number does not imply a correct image. Especially if you truncated larger images to 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. You might, however, find information about the (original) file size in there, I recommend just dumping the FileHeaders for some requests.

like image 63
mrd0ll4r Avatar answered Feb 05 '26 04:02

mrd0ll4r



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!