gin-gonic中的多部分文件上传验证

huangapple go评论101阅读模式
英文:

Multipart File Upload Validation in gin-gonic

问题

我正在尝试为基于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()

	// 其他实现细节
}

即使提供了处理程序,我仍然在Go代码中遇到了panic。请告诉我我在实现中漏掉了什么。

谢谢。

http: 没有该文件
File is nil.
http: 没有该文件
*****
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)
英文:

I am trying to add validation for the go based web application based on GIN framework. On the web page I am selecting a file and submitting and the server is processing it.
On the server side I am try to add validation to check if the file has been given or not. If not then redirect back to original page.

	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 
}

Even after providing the handling I am getting a panic in the go code. Please let me know what in the implementation am I missing.

Thanks.

	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)

答案1

得分: 4

  1. 请不要重新定义panic。这会让所有了解panic工作原理的人感到困惑。
  2. 在Go语言中,与nil进行比较有点棘手。它可能不会按照你的预期工作:https://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go。FormFile返回一个接口,所以如果你想要用nil进行检查,你必须将其转换为底层结构,或者使用第二个参数,其类型是可用的。
  3. 这不仅适用于GIN,它是Go语言的HTTP实现的一部分:http://golang.org/pkg/net/http/#Request.FormFile
英文:
  1. Please do not redefine panic. It will confuse everyone who knows how panic works.
  2. Comparison with nil is a bit tricky in Go. It may work not as you expect: https://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go. FormFile returns interface so you have to cast it to underlying structure if you want to check it with nil OR use the second parameter, type of which is available.
  3. This is not specific to GIN, it is part of the Go's HTTP implementation: http://golang.org/pkg/net/http/#Request.FormFile

答案2

得分: 0

我明白我在panic处理方面犯了错误。如果我在c.HTML之后添加返回语句,验证将会起作用。这将阻止函数执行其余的代码。感谢@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 
}
英文:

I understand that I have made mistake with the panic handling. The validation is working if I add the return statement after the c.HTML.
This will stop the function from executing the rest of the code.
Thanks to @AlexAtNet for his advice and I will keep in mind in future.

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 
} 

huangapple
  • 本文由 发表于 2015年8月4日 12:42:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/31800843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定