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
}