I have an endpoint that should send an email and an image as multipart/form-data with the method PUT.
I always get the ParseMultipartForm error: multipart: NextPart: EOF when sending the data. It's not a problem with the maxUploadSize because its value is 20MB and the image I'm sending is way less than 20MB. Also, the image exists and the path is correct.
The cURL command used is the one below (also tried using Insomnia):
curl --request PUT \
--url http://localhost:8080/upload-image \
--header 'Content-Type: multipart/form-data' \
--form [email protected] \
--form image=@/home/images/ad.jpg
When I print the r value as soon as it enters in the function, it shows the following result:
&{Method:PUT URL:/upload-image Proto:HTTP/1.1 ProtoMajor:1 ProtoMinor:1 Header:map[Accept:[*/*] Content-Length:[22941] Content-Type:[multipart/form-data; boundary=------------------------111a7e49ac62697b] User-Agent:[curl/7.81.0]] Body:0xc000450200 GetBody:<nil> ContentLength:22941 TransferEncoding:[] Close:false Host:localhost:8080 Form:map[] PostForm:map[] MultipartForm:<nil> Trailer:map[] RemoteAddr:127.0.0.1:59296 RequestURI:/upload-image TLS:<nil> Cancel:<nil> Response:<nil> ctx:0xc000592000 pat:<nil> matches:[] otherValues:map[]}
The code is below (I had to modify it a bit for security purposes, but in essence, that's it):
type UploadImageRequest struct {
Email string `json:"email"`
}
func (api *Api) ValidateRequest(w http.ResponseWriter, r *http.Request) (*UploadImageRequest, error) {
r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
err := r.ParseMultipartForm(maxUploadSize)
if err != nil {
log.Printf("ParseMultipartForm error: %v", err)
return nil, err
}
email := r.FormValue("email")
if email == "" {
return nil, err
}
return &UploadImageRequest{
Email: email,
}, nil
}
func (api *Api) UploadImage(w http.ResponseWriter, r *http.Request) {
fmt.Println("%+v", r)
uploadImageRequest, err := api.ValidateRequest(w, r)
if err != nil {
api.app.Respond(err, w, nil)
return
}
image := r.MultipartForm.File["image"]
if len(image) == 0 {
api.app.RespondError(nil, w, http.StatusBadRequest, "Image file is required")
return
}
// ...
}
-
const maxUploadSize = 20 * 1024 * 1024Yuri Costa– Yuri Costa2025年01月07日 12:51:15 +00:00Commented Jan 7, 2025 at 12:51
2 Answers 2
Aren't you reading the request body, like using io.ReadAll(r.Body), before calling ParseMultipartForm? If the body is read, even partially, beforehand, the multipart parser will encounter an EOF error, resulting in the message: Error parsing multipart form: multipart: NextPart: EOF.
2 Comments
data, err := io.ReadAll(r.Body) to see if something different pops up, but the body was empty too.I suspect that at this step lead to error EOF.
http.MaxBytesReader(w, r.Body, maxUploadSize)
Please try to use:
err := r.ParseMultipartForm(32 << 20) // max memory of 32MB - adjust to how many you want
After that, if you had more process before upload to storage, maybe the result uploaded to storage become the blank image. Please add
file, err := img.Open() // This is the step you open the image and process something, maybe get size, height, width,...
file.Seek(0, 0)
1 Comment
MaxBytesReader line and changed to a direct value instead of a variable in ParseMultipartForm but still getting ParseMultipartForm error: multipart: NextPart: EOF