如何动态更改 HTTP 服务器的静态文件目录?

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

How do I dynamically change static files directory of the http server?

问题

我有以下一段代码,用于从静态文件目录(staticFilesDir)提供静态文件:

for _, prefix := range []string{"css", "img", "js", "static"} {
    prefix = "/" + prefix + "/"
    fs := http.FileServer(http.Dir(staticFilesDir + prefix))
    r.PathPrefix(prefix).Handler(http.StripPrefix(prefix, fs))
}

这个目录会不时地发生变化,目前我每次都需要重新启动服务器进程才能使用新的值。

如何在不重新启动整个进程的情况下重新配置/重新加载FileServer

此外,还有一个复杂性:HTTP服务器的其他处理程序正在执行长时间运行的作业(包括子进程等),我希望在重新加载期间保持不变。

这个相当典型的任务有什么标准解决方案?

英文:

I have the following piece of code, that serves static files from a static files directory (staticFilesDir):

for _, prefix := range []string{"css", "img", "js", "static"} {
    prefix = "/" + prefix + "/"
    fs := http.FileServer(http.Dir(staticFilesDir + prefix))
    r.PathPrefix(prefix).Handler(http.StripPrefix(prefix, fs))
}

This directory changes from time to time, and currently I always need to restart the server process to use the new value.

How can I reconfigure/reload the FileServer without restarting the whole process?

Additional complication to that: other handlers of the http server are executing long-running jobs (incl. child processes etc.), that I would like to keep untouched during this reload.

What is the standard solution of this quite typical task?

答案1

得分: 4

你可以在中间添加一层间接性:

type MyFileServer struct {
   sync.RWMutex
   http.FileServer
}

func (f *MyFileServer) SetDir(dir string) {
    f.Lock()
    defer f.Unlock()
    f.FileServer = http.FileServer(http.Dir(dir))
}

func (f *MyFileServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
   f.RLock()
   defer f.RUnlock()
   f.FileServer.ServeHTTP(w, req)
}

这段代码中,MyFileServer 结构体包含了一个 sync.RWMutex 和一个 http.FileServerSetDir 方法用于设置文件目录,它会获取写锁并在函数结束时释放锁,然后将 http.FileServer 初始化为指定目录的文件服务器。ServeHTTP 方法用于处理 HTTP 请求,它获取读锁并在函数结束时释放锁,然后调用 http.FileServerServeHTTP 方法来处理请求。

英文:

You can add a level of indirection in between:

type MyFileServer struct {
   sync.RWMutex
   http.FileServer
}

func (f *MyFileServer) SetDir(dir string) {
    f.Lock()
    defer f.Unlock()
    f.FileServer=http.FileServer(dir)
}


func (f *MyFileServer) ServeHTTP(w http.ResponseWriter,req *http.Request) {
   f.RLock()
   defer f.RUnlock()
   f.FileServer.ServeHTTP(w,req)
}

huangapple
  • 本文由 发表于 2021年8月11日 02:55:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/68732197.html
匿名

发表评论

匿名网友

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

确定