Golang - How to check multipart.File information

When a user uploads a file using r.FormFile ("file"), you get multipart.File, multipart.FileHeader and an error.

My question is how easy it is to get information about the downloaded file, for example, size, as well as the image that it has, etc. etc.

I literally did not know where to start, so any help would be great.

+9
source share
4 answers

The file name and MIME type can be obtained from the returned multipart.FileHeader .

Further metadata will depend on the type of file. If this is an image, you can use the DecodeConfig functions in the standard library for PNG , JPEG and GIF to get the dimensions (and color model).

There are many Go libraries available for other types of files that will have similar functions.

UPDATE: There is a good example for the golang-nuts mail group .

+7
source

To get the file size and MIME type:

 // Size constants const ( MB = 1 << 20 ) type Sizer interface { Size() int64 } func Sample(w http.ResponseWriter, r *http.Request) error { if err := r.ParseMultipartForm(5 * MB); err != nil { return err } // Limit upload size r.Body = http.MaxBytesReader(w, r.Body, 5*MB) // 5 Mb // file, multipartFileHeader, err := r.FormFile("file") // Create a buffer to store the header of the file in fileHeader := make([]byte, 512) // Copy the headers into the FileHeader buffer if _, err := file.Read(fileHeader); err != nil { return err } // set position back to start. if _, err := file.Seek(0, 0); err != nil { return err } log.Printf("Name: %#v\n", multipartFileHeader.Filename) log.Printf("Size: %#v\n", file.(Sizer).Size()) log.Printf("MIME: %#v\n", http.DetectContentType(fileHeader)) } 

Output Example:

 2016/12/01 15:00:06 Name: "logo_35x30_black.png" 2016/12/01 15:00:06 Size: 18674 2016/12/01 15:00:06 MIME: "image/png" 
+8
source

You can get approximate file size information from the Content-Length header. This is not recommended as this title can be changed.

It is best to use the ReadFrom method:

 clientFile, handler, err := r.FormFile("file") // r is *http.Request var buff bytes.Buffer fileSize, err := buff.ReadFrom(clientFile) fmt.Println(fileSize) // this will return you a file size. 
+1
source

Another way that I found fairly simple for this type of testing is to put the test resources in the test_data directory relative to the package. In my test file, I usually create an assistant that creates an instance of * http.Request, which allows me to run the table test for multipart.File quite easily (error checking removed for brevity).

 func createMockRequest(pathToFile string) *http.Request { file, err := os.Open(pathToFile) if err != nil { return nil } defer file.Close() body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("file", filepath.Base(pathToFile)) if err != nil { return nil } _, _ = io.Copy(part, file) err = writer.Close() if err != nil { return nil } // the body is the only important data for creating a new request with the form data attached req, _ := http.NewRequest("POST", "", body) req.Header.Set("Content-Type", writer.FormDataContentType()) return req } 
0
source

Source: https://habr.com/ru/post/947389/


All Articles