Http 使用mime/multipart上载会损坏文件

Http 使用mime/multipart上载会损坏文件,http,go,Http,Go,我写了一个服务器,它有一个上传图片的路径。这是一个接收一些参数的表单:标题、说明、可见性和图片。该页面还使用身份验证标题 func UploadPictureRoute(prv *services.Provider) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user, err := auth.ValidateRequest(prv, w, r) if

我写了一个服务器,它有一个上传图片的路径。这是一个接收一些参数的表单:
标题
说明
可见性
图片
。该页面还使用
身份验证
标题

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),
        }

        pict, err = dal.CreatePicture(prv, pict)
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            return
        }

        outputFile, err := os.Create(parentFolder + strconv.FormatInt(*pict.ID, 10) + "." + pict.Ext)
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            dal.DeletePicture(prv, pict)
        }
        defer outputFile.Close()

        _, err = io.Copy(outputFile, file)
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            return
        }
// Responding 
    }
}
此代码使服务器崩溃。图片的mimetype变为
application/octet stream
,图像标题被破坏(它仍然在一些编辑器中打开,但EyesofNome基本上说图片不是JPG/PNG文件,因为它在开始时找不到幻数)

如何修复HTTP go客户端以成功上载图片?

我找到了一个解决方案:


克隆此文件,如果发现任何问题,请在此处进行注释。

调用
mimetype.DetectReader(文件)
读取部分文件。调用
\uu0,err=io.Copy(pict,file)
读取文件的其余部分。要读取整个文件,请在调用
io.Copy
之前返回偏移量0

文件在偏移量0处打开。调用
Open
后,无需立即寻找偏移量0

通过交换呼叫顺序修复此问题:

...

mime, _, err := mimetype.DetectReader(file)
if err != nil {
    fmt.Println("Can't read the file")
    return
}

// Rewind to the start of the file
_, err = file.Seek(0, io.SeekStart)
if err != nil {
    fmt.Println("Can't read the file")
    return
}

...
服务器也有类似的问题。检测到类型后倒带:

mimeType, _, err := mimetype.DetectReader(file) // Package gabriel-vasile/mimetype
if err != nil {
    w.WriteHeader(http.StatusBadRequest)
    return
}

// Rewind to the start of the file
_, err = file.Seek(0, io.SeekStart)
if err != nil {
    w.WriteHeader(http.StatusInternalServerError)
    return
}

图片现在被正确地检测为图像,但一旦上传,它仍然被破坏(在gnome眼中也是这个问题)哦,是的,这是显而易见的。谢谢有什么线索可以解释为什么在《邮递员》中会起作用吗?你必须用你的话来解释作者的问题及其解决方案。
mimeType, _, err := mimetype.DetectReader(file) // Package gabriel-vasile/mimetype
if err != nil {
    w.WriteHeader(http.StatusBadRequest)
    return
}

// Rewind to the start of the file
_, err = file.Seek(0, io.SeekStart)
if err != nil {
    w.WriteHeader(http.StatusInternalServerError)
    return
}