英文:
Log 404 on http.FileServer
问题
我正在使用http.FileServer
从dirPath
提供JPEG图像:
http.Handle("/o/", http.StripPrefix(
path.Join("/o", dirPath), http.FileServer(http.Dir(dirPath))))
我不明白的是如何在请求不存在的文件时进行日志记录。当我使用浏览器发出请求时,我可以看到http.FileServer
返回404页面未找到,但在服务器控制台上却没有显示。
英文:
I'm serving jpeg images from dirPath
using http.FileServer
with:
http.Handle("/o/", http.StripPrefix(
path.Join("/o", dirPath), http.FileServer(http.Dir(dirPath))))
What I don't understand is how to log when a request is made for a file that does not exist. I can see http.FileServer
returning 404 page not found when I make a request with the browser, but not on the server console.
答案1
得分: 12
http.StripPrefix()
和http.FileServer()
返回的http.Handler
不会记录HTTP 404错误。您需要扩展它们的功能以实现您想要的效果。
我们可以将http.StripPrefix()
或http.FileServer()
返回的http.Handler
值包装在另一个http.Handler
或http.HandlerFunc
中。一旦包装了处理程序,当然要注册包装器。
包装器的实现将简单地调用被包装的处理程序,一旦它返回,就可以检查HTTP响应状态码。如果是错误(或特定的HTTP 404 Not Found),可以适当地记录它。
问题是http.ResponseWriter
不支持读取响应状态码。我们可以做的是还包装http.ResponseWriter
,当写入状态码时,我们将存储它以供以后使用。
我们的http.ResponseWriter
包装器:
type StatusRespWr struct {
http.ResponseWriter // 我们嵌入http.ResponseWriter
status int
}
func (w *StatusRespWr) WriteHeader(status int) {
w.status = status // 为我们自己存储状态
w.ResponseWriter.WriteHeader(status)
}
以及包装http.Handler
:
func wrapHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
srw := &StatusRespWr{ResponseWriter: w}
h.ServeHTTP(srw, r)
if srw.status >= 400 { // 400+代码是错误代码
log.Printf("在提供路径%s时出现错误状态码:%d",
srw.status, r.RequestURI)
}
}
}
以及创建文件服务器、包装并注册的主要函数:
http.HandleFunc("/o/", wrapHandler(
http.StripPrefix("/o", http.FileServer(http.Dir("/test")))))
panic(http.ListenAndServe(":8181", nil))
请求不存在文件时的示例输出:
2015/12/01 11:47:40 在提供路径/o/sub/b.txt2时出现错误状态码:404
英文:
The http.Handler
s returned by http.StripPrefix()
and http.FileServer()
do not log HTTP 404 errors. You have to extend their functionality in order to achieve what you want.
We can wrap the http.Handler
value returned by http.StripPrefix()
or http.FileServer()
in another http.Handler
or http.HandlerFunc
. Once you wrapped the handler, register the wrapper of course.
The wrapper implementation will simply called the wrapped one, and once it returns, can inspect the HTTP response status code. If it is an error (or specifically HTTP 404 Not Found), can log it appropriately.
Problem is http.ResponseWriter
does not support reading the response status code. What we can do is we also wrap the http.ResponseWriter
and when status code is written, we will store it for later to be available.
Our http.ResponseWriter
wrapper:
type StatusRespWr struct {
http.ResponseWriter // We embed http.ResponseWriter
status int
}
func (w *StatusRespWr) WriteHeader(status int) {
w.status = status // Store the status for our own use
w.ResponseWriter.WriteHeader(status)
}
And wrapping the http.Handler
:
func wrapHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
srw := &StatusRespWr{ResponseWriter: w}
h.ServeHTTP(srw, r)
if srw.status >= 400 { // 400+ codes are the error codes
log.Printf("Error status code: %d when serving path: %s",
srw.status, r.RequestURI)
}
}
}
And the main function creating a file server, wrapping it and registering it:
http.HandleFunc("/o/", wrapHandler(
http.StripPrefix("/o", http.FileServer(http.Dir("/test")))))
panic(http.ListenAndServe(":8181", nil))
Example output when requesting a non-existing file:
2015/12/01 11:47:40 Error status code: 404 when serving path: /o/sub/b.txt2
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论