How to avoid serving template files by Go

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

How to avoid serving template files by Go

问题

我正在使用Go编写一个小型网站,并遇到了一些问题,不知道如何解决。基本思路是有一个名为/themes/的单个文件夹,我们将在其中放置所有的主题,例如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文件夹,并将其中的内容提供给客户端。

提前感谢您的帮助。

英文:

I'm writting small website on Go, and i found some problems, that i dont know how to solve. So...
The basic idea is to have one single folder for themes, called /themes/ where we will put all our themes, f.e. classic, modern, etc.
The directory tree will looks like:

/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

So, my http handlers:

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

The Problem

The problem is that my templates files can be opened from the outside, if i open path http://localhost/static/index.html, so i need solution to:

  1. Deny /static/, show 404.
  2. Deny /static/*.html, show 404.
  3. Allow /static/{folder_name}/{file_name} so in future i can add img folder or fonts folder, and content inside of them will be served by server to client.

Thanks in advice.

答案1

得分: 0

简单的方法是实现自己的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
	}

	// 这将拒绝访问目录列表
	if stat.IsDir() {
		return nil, os.ErrNotExist
	}

	// 这将拒绝访问除了<prefix>/css/...之外的任何内容
	if !strings.HasPrefix(name, "/css/") {
		return nil, os.ErrNotExist
	}

	return f, nil
}

现在你可以在主函数中这样使用它:

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

Easy way is to implement your own 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
}

Now you can use it in your main like so:

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

huangapple
  • 本文由 发表于 2017年2月23日 01:34:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/42398498.html
匿名

发表评论

匿名网友

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

确定