From: http://capotej.com/
转者按:本文介绍了如何hook一个http的处理函数,从而加入自定义的内容。
Most modern web stacks allow the “filtering” of requests via stackable/composable middleware,allowing you to cleanly separate cross-cutting concerns from your web application. This weekend I needed to hook into go’s
http.FileServer
and was pleasantly surprised how easy it was to do.
Let’s start with a basic file server for/tmp
:
main.go
1
2
3
|
func main() { http.ListenAndServe(":8080", FileServer(Dir"/tmp"))) } |
This starts up a local file server at :8080. How can we hook into this so we can run some code before file requests are served? Let’s look at the method signature forhttp.ListenAndServe
:
1
|
addr stringhandler Handler) error |
So it looks likehttp.FileServer
returns aHandler
that knows how to serve files given a root directory. Now let’s look at theHandler
interface:
type Handler interface ServeHTTPResponseWriter*Request) Because of go’s granular interfaces,any object can be aHandler so long as it implementsServeHTTP . It seems all we need to do is construct our ownHandler that wrapshttp.FileServer ’s handler. There’s a built in helper for turning ordinary functions into handlers calledhttp.HandlerFunc :
Then we just wraphttp.FileServer like so:
main.go
1
2
3
4
5
6
7
8
9
10
11
12
|
OurLoggingHandlerh Handler { return HandlerFunc(w r ) fmtPrintln(*rURL) hw) }) } fileHandler := )) wrappedHandler fileHandlerwrappedHandler Go has a bunch of other builtinhandlerslikeTimeoutHandlerandRedirectHandlerthat can be mixed and matched the same way.
另一种方式参考https://github.com/philsong/golang_samples/blob/master/src/emvdecoder/emvdecoder.go
type TraceHandler struct {
h http.Handler
n int
}
func (r *TraceHandler) ServeHTTP(w http.ResponseWriter,req *http.Request) {
r.n++
fmt.Printf("counter = %d\n",r.n) //why counter always zero
fmt.Println("get",req.URL.Path," from ",req.RemoteAddr)
r.h.ServeHTTP(w,req)
}
func main() {
port := "9090" //Default port
if len(os.Args) > 1 {
port = strings.Join(os.Args[1:2],"")
}
h := http.StripPrefix("/icclogs/",http.FileServer(http.Dir("./logs/")))
http.Handle("/icclogs/",&TraceHandler{h: h,n: 0})
println("Listening on port ",port,"...")
err := http.ListenAndServe(":"+port,nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ",err)
}
} 原文链接:https://www.f2er.com/go/191233.html
| |