【问题标题】:Multipart File Upload Validation in gin-gonicgin-gonic 中的多部分文件上传验证
【发布时间】:2015-10-26 08:38:27
【问题描述】:

我正在尝试为基于 GIN 框架的基于 Go 的 Web 应用程序添加验证。在网页上,我正在选择一个文件并提交,服务器正在处理它。 在服务器端,我尝试添加验证以检查文件是否已提供。如果没有,则重定向回原始页面。

    func panic(err error)  {
        if err != nil {
            log.Println(err)
        }
    }

    func displayTable (c *gin.Context) {    
    file, _ , err := c.Request.FormFile("file")
    panic(err)
    if file == nil {
        log.Println("File is nil.")
        log.Println(err)
        log.Println("*****")
        c.HTML(http.StatusInternalServerError, "index.tmpl", gin.H{
            "title": "Select the input file","error" : "Please select the input file.",
        })      
    } else {
        defer file.Close()
    }
    filename := strconv.FormatInt(time.Now().Unix(),10) 
    out, err := os.Create("./tmp/"+filename+".xml")
    panic(err)
    defer out.Close()
    _, err = io.Copy(out, file)
    panic(err)
    xmlFile, err := os.Open("./tmp/"+filename+".xml")
    panic(err)
    defer xmlFile.Close()

    // Other Implementation Details 
}

即使在提供了处理之后,我仍然在 go 代码中感到恐慌。请让我知道我在实现中缺少什么。

谢谢。

    http: no such file
    File is nil.
    http: no such file
    *****
    2015/08/04 13:19:10 Panic recovery -> runtime error: invalid memory address or nil pointer dereference
    c:/go/src/runtime/panic.go:387 (0x414d36)
    c:/go/src/runtime/panic.go:42 (0x4142a5)
    c:/go/src/runtime/os_windows.go:42 (0x414066)
    c:/go/src/io/io.go:362 (0x45268f)
    D:/code/src/exmp/serverexmaple.go:45 (0x40168f)
            displayTable: _, err = io.Copy(out, file)
    D:/code/src/github.com/gin-gonic/gin/context.go:95 (0x49f8ea)
            (*Context).Next: c.handlers[c.index](c)
    D:/code/src/github.com/gin-gonic/gin/logger.go:56 (0x4ac490)
            func.007: c.Next()
    D:/code/src/github.com/gin-gonic/gin/context.go:95 (0x49f8ea)
            (*Context).Next: c.handlers[c.index](c)
    D:/code/src/github.com/gin-gonic/gin/recovery.go:43 (0x4acc80)
            func.009: c.Next()
    D:/code/src/github.com/gin-gonic/gin/context.go:95 (0x49f8ea)
            (*Context).Next: c.handlers[c.index](c)
    D:/code/src/github.com/gin-gonic/gin/gin.go:292 (0x4a46d5)
            (*Engine).handleHTTPRequest: context.Next()
    D:/code/src/github.com/gin-gonic/gin/gin.go:273 (0x4a4459)
            (*Engine).ServeHTTP: engine.handleHTTPRequest(c)
    c:/go/src/net/http/server.go:1703 (0x468415)
    c:/go/src/net/http/server.go:1204 (0x466408)
    c:/go/src/runtime/asm_386.s:2287 (0x438ea1)

【问题讨论】:

  • 您应该修改您的代码并实际包含您所拥有的,这不可能是您的真实代码:file, _ , err := c.Request.FormFile("file"); panic(err) 无论如何,错误很明显,2015/08/04 13:19:10 Panic recovery -> runtime error: invalid memory address or nil pointer dereference 您很可能会尝试取消引用nil。
  • @user3591723 如果您看到与代码匹配的错误D:/code/src/exmp/serverexmaple.go:45 (0x40168f) displayTable: _, err = io.Copy(out, file) 是问题区域。问题是当文件值为 nil 时,它不会重定向到错误页面,而是执行其余代码,因此在尝试读取 nil 值时会出现恐慌。这是 gin 框架的常见行为吗?
  • 我不确定 gin 的常见行为是什么,为什么不直接从您的函数返回?另外,你为什么要重新定义panic?.. 这是一个内置函数,不重新定义它对可读性很重要。

标签: validation go go-gin


【解决方案1】:
  1. 请不要重新定义panic。这会让所有知道panic 工作原理的人感到困惑。
  2. 在 Go 中与 nil 进行比较有点棘手。它可能不会像您预期的那样工作:Check for nil and nil interface in Go。 FormFile 返回接口,所以如果你想用 nil 检查它,你必须将它转换为底层结构,或者使用第二个参数,其类型可用。
  3. 这不是特定于 GIN,它是 Go 的 HTTP 实现的一部分:http://golang.org/pkg/net/http/#Request.FormFile

【讨论】:

  • 感谢第 1 点和第 2 点,以后会牢记。但是如果我在 `c.HTML(http.StatusInternalServerError, "index.tmpl", gin.H{"title": "Select the input file","error" : "请选择输入文件之后添加return 语句.",}) ` 没有显示恐慌并且重定向似乎有效。
  • 哈,很明显!在原始代码中,您检查文件是否为零并调用_, err = io.Copy(out, file),即使它是零。当然你应该加上回报。
【解决方案2】:

我了解我在处理 panic 时犯了错误。如果我在 c.HTML 之后添加 return 语句,则验证有效。 这将阻止函数执行其余代码。 感谢@AlexAtNet 的建议,我会记住的。

if file == nil {
    log.Println("File is nil.")
    log.Println(err)
    log.Println("*****")
    c.HTML(http.StatusInternalServerError, "index.tmpl", gin.H{
        "title": "Select the input file","error" : "Please select the input file.",
    })   
    return 
} 

【讨论】:

    猜你喜欢
    • 2021-02-28
    • 2017-08-09
    • 2017-07-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2012-04-10
    • 1970-01-01
    相关资源
    最近更新 更多