英文:
How to avoid serving template files by Go
问题
我正在使用Go编写一个小型网站,并遇到了一些问题,不知道如何解决。基本思路是有一个名为/themes/
的单个文件夹,我们将在其中放置所有的主题,例如classic
、modern
等。
目录结构如下:
/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
,我的模板文件可以从外部打开,所以我需要解决以下问题:
- 拒绝访问
/static/
,显示404错误。 - 拒绝访问
/static/*.html
,显示404错误。 - 允许访问
/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:
- Deny
/static/
, show 404. - Deny
/static/*.html
, show 404. - Allow
/static/{folder_name}/{file_name}
so in future i can addimg
folder orfonts
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))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论