Альтернатива Golang для python / flask send_from_directory ()

У меня есть URL-адреса изображений:

/book/cover/Computer_Science.png

но местоположение изображения на самом деле существует под

/uploads/img/Computer_Science.png

Я использую Gin framework. Есть ли в Gin или встроенных функциях Golang какая-нибудь команда вроде send_from_directory() из Flask?

Если нет, не могли бы вы рассказать, как это сделать?

Спасибо!


person rnk    schedule 03.06.2017    source источник


Ответы (1)


Используйте Context.File gin для обслуживания содержимого файла. Этот метод внутренне вызывает встроенную функцию https://golang.org/pkg/net/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)
    }

    //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)
})

Обновить

Как указывает zerkms, путь необходимо очистить перед его передачей Context.File. В сниппет добавлено простое дезинфицирующее средство. Пожалуйста, приспосабливайтесь к своим потребностям.

person putu    schedule 03.06.2017
comment
Я думаю, стоит упомянуть, что также необходимо проверить, находится ли полученный нормализованный путь в ожидаемом каталоге, иначе можно запросить /book/cover/../../../../../../../etc/passwd - person zerkms; 04.06.2017
comment
@zerkms Спасибо, вы правы. Я обновил ответ. - person putu; 04.06.2017