2 回答

TA貢獻1895條經驗 獲得超3個贊
為了使中間件與 . 解耦,http.FileServer
在包裝它時,您可以傳遞一個特定的實現http.ResponseWriter
:
累積標頭,以防它們需要被丟棄(如果
WriteHeader
使用 404 調用)如果
WriteHeader
使用 404 調用:取消累積的標題
發送自定義 404
忽略
Write
來自包裝處理程序的調用如果
WriteHeader
未調用,或使用非 404 調用,則:將累積的標頭發送到真實的
ResponseWriter
WriteHeader
將andWrite
呼叫路由到真實的ResponseWriter
type notFoundInterceptorWriter struct {
rw http.ResponseWriter // set to nil to signal a 404 has been intercepted
h http.Header // set to nil to signal headers have been emitted
notFoundHandler http.Handler
r *http.Request
}
func (rw *notFoundInterceptorWriter) Header() http.Header {
if rw.h == nil && rw.rw != nil {
return rw.rw.Header()
}
return rw.h
}
func (rw *notFoundInterceptorWriter) WriteHeader(status int) {
if status == http.StatusNotFound {
rw.notFoundHandler.ServeHTTP(rw.rw, rw.r)
rw.rw = nil
} else {
for k, vs := range rw.h {
for _, v := range vs {
rw.rw.Header().Add(k, v)
}
}
rw.rw.WriteHeader(status)
}
rw.h = nil
}
func (rw *notFoundInterceptorWriter) Write(b []byte) (int, error) {
if rw.rw != nil {
return rw.rw.Write(b)
}
// ignore, so do as if everything was written OK
return len(b), nil
}
func StaticSiteHandler(h, notFoundHandler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w = ¬FoundInterceptorWriter{
rw: w,
h: make(http.Header),
notFoundHandler: notFoundHandler,
r: r,
}
h.ServeHTTP(w, r)
})
}

TA貢獻1790條經驗 獲得超9個贊
您可以在提供文件之前統計文件以查看它是否存在。根據需要調整 404 處理程序(發出模板等)
package main
import (
"net/http"
"path"
"os"
)
func init() {
http.Handle("/", staticHandler)
}
func error404Handler(w http.ResponseWriter, r *http.Request) {
http.Error(w, "404 not found", http.StatusNotFound)
}
func staticHandler(w http.ResponseWriter, r *http.Request) {
name := path.Clean(r.URL.Path)
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
error404Handler(w, r)
return
}
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
return http.ServeFile(w, r, name)
}
- 2 回答
- 0 關注
- 484 瀏覽
添加回答
舉報