I am a beginner with go-lang. I met a problem when I uploaded a file with html template. I google a lot but not solved.
<input type="file" name="myfile"/>
Use func (*Request) FormFile get the file.
file, header, err := req.FormFile("receipt")
But how to validate the file whether it is empty from server side? I know I can read request.Body to find whether myfile is empty.
Is there a better way to implement it?
I don't think it's possible to know the size of the file until you read it. See this answer:
To read the file content is the only reliable way. Having said that, if the content-lenght is present and is too big, to close the connection would be a reasonable thing to do.
So I guess you'll have to read a part of the content into a small temporary buffer and look at the size.
If you want to validate, whether the user even sent a file, you can check against http.ErrMissingFile
:
file, header, err := r.FormFile("f")
switch err {
case nil:
// do nothing
case http.ErrMissingFile:
log.Println("no file")
default:
log.Println(err)
}
No, you can't find the length of a file without reading it. (You can try to use Content-Length header, but you have to know that it can be modified and thus not reliable).
Here is how you can get the file size:
file, handler, err := r.FormFile("receipt") // r is *http.Request
var buff bytes.Buffer
fileSize, err := buff.ReadFrom(file)
fmt.Println(fileSize) // this will return you a file size.
You can read the file size from the header variable (in your example), which is a FileHeader type, returned by FormValue, and contains the size of the file:
file, header, err := req.FormFile("receipt")
if err != nil || header.Size == 0 {
// file was not sent
} else {
// process file
}
Though I'm not sure how reliable is this data in terms of security (I guess an attacker could fake the headers sent to the server maliciously).