gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.28k stars 7.99k forks source link

The multipart form data resolve issue #2613

Open zoujialing125 opened 3 years ago

zoujialing125 commented 3 years ago

Question

If there any bug on multipart form data file receiving? Browser on windows 10 cannot receive response correctly when use auth middleware to reject the request before execute any operational function.

Description

By the way, no problem if use curl to send request directly or use postman to help construct the request.

// c.ShouldBind(&obj)  -- before return, browser received 401 correctly
c.JSON(401, gin.H{"test": "test"})
return
// c.ShouldBind(&obj)  -- after return, which means server does not do anything about the post data, browser will get connection_reset error

How to reproduce

import ( "github.com/gin-gonic/gin" "github.com/gin-contrib/cors" "mime/multipart" "net/http" "strings" )

type ProfileForm struct { Files []*multipart.FileHeader form:"files" binding:"required" Json string form:"json" binding:"required" }

func main() { router := gin.Default() router.Use(cors.New(cors.Config{ AllowMethods: []string{"PUT", "PATCH", "POST", "OPTIONS"}, AllowHeaders: []string{"Origin"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, AllowOriginFunc: func(origin string) bool { return true }, MaxAge: 12 * time.Hour, }))

// Set a lower memory limit for multipart forms (default is 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
    obj := ProfileForm{}

    if strings.Contains(c.GetHeader("content-type"), "multipart") {
        c.JSON(401, gin.H{"test": "test"})
        return
    }

    // Multipart form
    if err := c.ShouldBind(&obj); err != nil {
        c.JSON(406, gin.H{"error": err.Error()})
        return
    }

    form, _ := c.MultipartForm()
    files := form.File["upload[]"]

    for _, file := range files {
        log.Println(file.Filename)

        // Upload the file to specific dst.
        c.SaveUploadedFile(file, "./files")
    }
    c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
})
router.Run(":8080")

}


- Client Side

<!DOCTYPE html>

batara666 commented 2 years ago

any update?

lifest01 commented 1 month ago

same problem