【问题标题】:How to avoid serving template files by Go如何避免通过 Go 提供模板文件
【发布时间】:2017-02-23 01:54:34
【问题描述】:

我正在用 Go 编写小型网站,但我发现了一些我不知道如何解决的问题。所以... 基本想法是为主题创建一个文件夹,名为/themes/,我们将在其中放置所有主题,f.e. classicmodern等 目录树如下所示:

/themes/
    classic/
        index.html
        header.html
        footer.html
        css/
            style.css
        js/
            lib.js
    modern/
        index.html
        header.html
        footer.html
        css/
            style.css
        js/
            lib.js

所以,我的 http 处理程序:

func main() {
    reloadConfig()

    http.HandleFunc("/", homeHandler)

    http.HandleFunc("/reloadConfigHandler/", reloadConfigHandler)

    // TODO: Theme loads html files also
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("themes/"+config.Theme+"/"))))
    http.ListenAndServe(":80", nil)
}

问题

问题是我的模板文件可以从外部打开,如果我打开路径http://localhost/static/index.html,所以我需要解决方案:

  1. 拒绝/static/,显示404。
  2. 拒绝/static/*.html,显示404。
  3. 允许/static/{folder_name}/{file_name},这样以后我可以添加img 文件夹或fonts 文件夹,其中的内容将由服务器提供给客户端。

感谢您的建议。

【问题讨论】:

  • 添加/static/css//static/js/ 而不是/static/ 怎么样?和你现在做的一样,只是两次,路径不同。
  • @ryan 这是解决方案,但不灵活.. 有一天我会使用/css_minified/,也可能添加/fonts//images/ 或其他一些文件夹。这是解决方案,但不是优雅的方式。
  • 混合模板和静态文件在 $current_year 中被认为是不优雅的事情 =) 如果您能够将 cssjs 嵌套在另一个 assets 目录中并将模板放入templates(该部分是可选的),也可以。
  • @Ryan 这也是将cssjs 文件夹放入/assets/ 的好主意。也许比为文件编写自己的处理程序更好。

标签: go


【解决方案1】:

简单的方法是实现你自己的http.FileSystem:

type fileSystem struct {
    http.FileSystem
}

func (fs fileSystem) Open(name string) (http.File, error) {
    f, err := fs.FileSystem.Open(name)
    if err != nil {
        return nil, err
    }

    stat, err := f.Stat()
    if err != nil {
        return nil, err
    }

    // This denies access to the directory listing
    if stat.IsDir() {
        return nil, os.ErrNotExist
    }

    // This denies access to anything but <prefix>/css/...
    if !strings.HasPrefix(name, "/css/") {
        return nil, os.ErrNotExist
    }

    return f, nil
}

现在您可以像这样在 main 中使用它:

fs := http.FileServer(fileSystem{http.Dir("themes/"+config.Theme+"/")})    
http.Handle("/static/", http.StripPrefix("/static/", fs))

【讨论】:

  • 是的,这就是我需要的。谢谢。你能解释一下吗,是否有可能关闭从/static/index.html/static/ 的重定向。我不知道为什么会这样,但它是,而且只有 index.html,但 footer.html 是可以的。有什么方法可以在你的 func 中解决这个问题?
  • 您必须包装http.FileServer 返回的处理程序并将其捕获。这不是通过http.FileSystem 而是通过http.serveFile 处理的。无论如何,你为什么要关心?重定向后会导致 404。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 2017-12-03
  • 2012-05-09
  • 1970-01-01
  • 2011-01-16
相关资源
最近更新 更多