How to avoid serving template files by Go

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

How to avoid serving template files by Go

问题

我正在使用Go编写一个小型网站,并遇到了一些问题,不知道如何解决。基本思路是有一个名为/themes/的单个文件夹,我们将在其中放置所有的主题,例如classicmodern等。

目录结构如下:

  1. /themes/
  2. classic/
  3. index.html
  4. header.html
  5. footer.html
  6. css/
  7. style.css
  8. js/
  9. lib.js
  10. modern/
  11. index.html
  12. header.html
  13. footer.html
  14. css/
  15. style.css
  16. js/
  17. lib.js

所以,我的HTTP处理程序如下:

  1. func main() {
  2. reloadConfig()
  3. http.HandleFunc("/", homeHandler)
  4. http.HandleFunc("/reloadConfigHandler/", reloadConfigHandler)
  5. // TODO: Theme loads html files also
  6. http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("themes/"+config.Theme+"/"))))
  7. http.ListenAndServe(":80", nil)
  8. }

问题

问题是,如果我打开路径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:

  1. /themes/
  2. classic/
  3. index.html
  4. header.html
  5. footer.html
  6. css/
  7. style.css
  8. js/
  9. lib.js
  10. modern/
  11. index.html
  12. header.html
  13. footer.html
  14. css/
  15. style.css
  16. js/
  17. lib.js

So, my http handlers:

  1. func main() {
  2. reloadConfig()
  3. http.HandleFunc("/", homeHandler)
  4. http.HandleFunc("/reloadConfigHandler/", reloadConfigHandler)
  5. // TODO: Theme loads html files also
  6. http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("themes/"+config.Theme+"/"))))
  7. http.ListenAndServe(":80", nil)
  8. }

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

  1. type fileSystem struct {
  2. http.FileSystem
  3. }
  4. func (fs fileSystem) Open(name string) (http.File, error) {
  5. f, err := fs.FileSystem.Open(name)
  6. if err != nil {
  7. return nil, err
  8. }
  9. stat, err := f.Stat()
  10. if err != nil {
  11. return nil, err
  12. }
  13. // 这将拒绝访问目录列表
  14. if stat.IsDir() {
  15. return nil, os.ErrNotExist
  16. }
  17. // 这将拒绝访问除了<prefix>/css/...之外的任何内容
  18. if !strings.HasPrefix(name, "/css/") {
  19. return nil, os.ErrNotExist
  20. }
  21. return f, nil
  22. }

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

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

Easy way is to implement your own http.FileSystem:

  1. type fileSystem struct {
  2. http.FileSystem
  3. }
  4. func (fs fileSystem) Open(name string) (http.File, error) {
  5. f, err := fs.FileSystem.Open(name)
  6. if err != nil {
  7. return nil, err
  8. }
  9. stat, err := f.Stat()
  10. if err != nil {
  11. return nil, err
  12. }
  13. // This denies access to the directory listing
  14. if stat.IsDir() {
  15. return nil, os.ErrNotExist
  16. }
  17. // This denies access to anything but <prefix>/css/...
  18. if !strings.HasPrefix(name, "/css/") {
  19. return nil, os.ErrNotExist
  20. }
  21. return f, nil
  22. }

Now you can use it in your main like so:

  1. fs := http.FileServer(fileSystem{http.Dir("themes/"+config.Theme+"/")})
  2. 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:

确定