使用 mime/multipart 上传会损坏文件

我写了一个服务器,有上传图片的路由。这是一个接收一些参数的表单:title、description和visibility。picture该页面还使用Authentication标题。


func UploadPictureRoute(prv *services.Provider) http.HandlerFunc {

    return func(w http.ResponseWriter, r *http.Request) {

        user, err := auth.ValidateRequest(prv, w, r)

        if auth.RespondError(w, err) {

            return

        }


        r.ParseMultipartForm(10 << 20) // 10 meg max


        title := r.FormValue("title")

        desc := r.FormValue("description")

        visib := r.FormValue("visibility")

        visibInt, err := strconv.Atoi(visib)

        visibility := int8(visibInt) // Visibility can be either 0, 1, 2


        if err != nil {

            w.WriteHeader(http.StatusBadRequest)

        }


        file, _, err := r.FormFile("picture")

        if err != nil {

            w.WriteHeader(http.StatusBadRequest)

            return

        }

        defer file.Close()


        mimeType, _, err := mimetype.DetectReader(file) // Package gabriel-vasile/mimetype

        if err != nil {

            w.WriteHeader(http.StatusBadRequest)

            return

        }


        if !utils.IsValidMimetype(mimeType) { // Basically just comparing to image/png, image/jpg. Crashes here

            w.WriteHeader(http.StatusBadRequest)

            return

        }


        parentFolder := prv.PicturePath + "/" + strconv.FormatInt(*user.ID, 10) + "/"


        _, err = os.Stat(parentFolder)

        if os.IsNotExist(err) {

            err = os.MkdirAll(parentFolder, os.ModePerm)

            if err != nil {

                w.WriteHeader(http.StatusInternalServerError)

                return

            }

        }


        pict := model.Picture{

            Title:       title,

            Description: desc,

            Creator:     &user,

            Visibility:  visibility,

            Ext:         utils.GetExtForMimetype(mimeType),

        }

这段代码会导致服务器崩溃。图片的mimetype变成application/octet-stream并且图像标题被破坏(它仍然在某些编辑器中打开,但EyesOfGnome基本上说图片不是JPG/PNG文件,因为它找不到开头的幻数)


如何修复HTTP go客户端才能成功上传图片?


人到中年有点甜
浏览 92回答 1
1回答

慕少森

调用mimetype.DetectReader(file)读取部分文件。调用 _, err = io.Copy(pict, file)读取文件的其余部分。要读取整个文件,请回溯到调用 之前的偏移量 0 io.Copy。文件在偏移量 0 处打开。调用 后无需立即查找偏移量 0 Open。通过交换调用顺序来修复问题:...mime, _, err := mimetype.DetectReader(file)if err != nil {&nbsp; &nbsp; fmt.Println("Can't read the file")&nbsp; &nbsp; return}// Rewind to the start of the file_, err = file.Seek(0, io.SeekStart)if err != nil {&nbsp; &nbsp; fmt.Println("Can't read the file")&nbsp; &nbsp; return}...服务器也有类似的问题。检测类型后回退:mimeType, _, err := mimetype.DetectReader(file) // Package gabriel-vasile/mimetypeif err != nil {&nbsp; &nbsp; w.WriteHeader(http.StatusBadRequest)&nbsp; &nbsp; return}// Rewind to the start of the file_, err = file.Seek(0, io.SeekStart)if err != nil {&nbsp; &nbsp; w.WriteHeader(http.StatusInternalServerError)&nbsp; &nbsp; return}
打开App,查看更多内容
随时随地看视频慕课网APP