简介
上一篇文章中,我们介绍了 gorilla web 开发工具包中的路由管理库gorilla/mux
,在文章最后我们介绍了如何使用中间件处理通用的逻辑。在日常 Go Web 开发中,开发者遇到了很多相同的中间件需求,gorilla/handlers(后文简称为handlers
)收集了一些比较常用的中间件。一起来看看吧~
关于中间件,前面几篇文章已经介绍的很多了。这里就不赘述了。handlers
库提供的中间件可用于标准库net/http
和所有支持http.Handler
接口的框架。由于gorilla/mux
也支持http.Handler
接口,所以也可以与handlers
库结合使用。这就是兼容标准的好处。
项目初始化&安装
本文代码使用 Go Modules。
创建目录并初始化:
$ mkdir gorilla/handlers && cd gorilla/handlers
$ go mod init github.com/darjun/go-daily-lib/gorilla/handlers
安装gorilla/handlers
库:
$ go get -u github.com/gorilla/handlers
下面依次介绍各个中间件和相应的源码。
日志
handlers
提供了两个日志中间件:
LoggingHandler
:以 Apache 的Common Log Format
日志格式记录 HTTP 请求日志;CombinedLoggingHandler
:以 Apache的Combined Log Format
日志格式记录 HTTP 请求日志,Apache 和 Nginx 默认都使用这种日志格式。
两种日志格式差别很小,Common Log Format
格式如下:
%h %l %u %t "%r" %>s %b
各个指示符含义如下:
%h
:客户端的 IP 地址或主机名;%l
:RFC 1413
定义的客户端标识,由客户端机器上的identd
程序生成。如果不存在,则该字段为-
;%u
:已验证的用户名。如果不存在,该字段为-
;%t
:时间,格式为day/month/year:hour:minute:second zone
,其中:-
day
:2位数字;month
:月份缩写,3个字母,如Jan
;year
:4位数字;hour
:2位数字;minute
:2位数字;second
:2位数字;zone
:+
或-
后跟4位数字;例如:
21/Jul/2021:06:27:33 +0800
%r
:包含 HTTP 请求行信息,例GET /index.html HTTP/1.1
;%>s
:服务器发送给客户端的状态码,例如200
;%b
:响应长度(字节数)。
Combined Log Format
格式如下:
%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"
可见相比Common Log Format
只是多了:
%{Referer}i
:HTTP 首部中的Referer
信息;%{User-Agent}i
:HTTP 首部中的User-Agent
信息。
对中间件,我们可以让它作用于全局,即全部处理器,也可以让它只对某些处理器生效。如果要对所有处理器生效,可以调用Use()
方法。如果只需要作用于特定的处理器,在注册时用中间件将处理器包装一层:
func index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World")
}
type greeting string
func (g greeting) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome, %s", g)
}
func main() {
r := mux.NewRouter()
r.Handle("/", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(index)))
r.Handle("/greeting", handlers.CombinedLoggingHandler(os.Stdout, greeting("dj")))
http.Handle("/", r)
log.Fatal(http.ListenAndServe(":8080", nil))
}
上面代码中LoggingHandler
只作用于处理函数index
,CombinedLoggingHandler
只作用于处理器greeting("dj")
。
运行代码,通过浏览器访问localhost:8080
和localhost:8080/greeting
:
::1 - - [21/Jul/2021:06:39:45 +0800] "GET