Golang中替代Python/Flask的send_from_directory()函数的方法是什么?

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

Golang alternative for python/flask send_from_directory()

问题

我有这些图片的URL:

/book/cover/Computer_Science.png

但实际上图片的位置是在

/uploads/img/Computer_Science.png

我正在使用 Gin框架。在Gin或内置的Golang函数中是否有类似Flask的send_from_directory()命令?

如果没有,你能分享一段代码片段来演示如何实现吗?

谢谢!

英文:

I have this image urls:

/book/cover/Computer_Science.png

but the location of the image actually exists under

/uploads/img/Computer_Science.png

I'm using Gin framework. Is there any command like Flask's send_from_directory() in Gin or in in-built Golang functions?

If not could you share a snippet of how to do it?

Thanks!

答案1

得分: 2

使用gin的Context.File方法来提供文件内容。该方法内部调用了http.ServeFile内置函数。代码片段如下:

import "path/filepath"

// ...
router := gin.Default()
// ...

router.GET("/book/cover/:filename", func(c *gin.Context) {
    rootDir := "/uploads/img/"
    name := c.Param("filename")
    filePath, err := filepath.Abs(rootDir + name)
    if err != nil {
        c.AbortWithStatus(404)
    }

    // 只允许访问rootDir下的文件/目录
    // 以下代码仅供示例,因为HasPrefix已被弃用。
    // 修复链接:https://github.com/golang/dep/issues/296
    if !filepath.HasPrefix(filePath, rootDir) {
        c.AbortWithStatus(404)
    }

    c.File(filePath)
})

更新

如zerkms所指出,传递给Context.File的路径名必须经过清理。在代码片段中添加了一个简单的清理器,请根据需要进行调整。

英文:

Use gin's Context.File to serve file content. This method internally calls http.ServeFile builtin function. The code snippets will be:

import "path/filepath"


// ...
router := gin.Default()
// ... 

router.GET("/book/cover/:filename", func(c *gin.Context) {
    rootDir := "/uploads/img/"
    name := c.Param("filename")
    filePath, err :=  filepath.Abs(rootDir + name)
    if err != nil {
        c.AbortWithStatus(404)
    }

    //Only allow access to file/directory under rootDir
    //The following code is for ilustration since HasPrefix is deprecated.
    //Replace with correct one when https://github.com/golang/dep/issues/296 fixed
    if !filepath.HasPrefix(filePath, rootDir) {
        c.AbortWithStatus(404)
    }

    c.File(filePath)
})

Update

As pointed by zerkms, the path name must be sanitized before passing it Context.File. Simple sanitizer is added in the snippet. Please adapt to your needs.

huangapple
  • 本文由 发表于 2017年6月4日 02:09:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/44347100.html
匿名

发表评论

匿名网友

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

确定