diff --git a/README.md b/README.md index 5044e8d..c6ac80e 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,13 @@ Add and initialize your program and execute it, that's it! package main import ( + "fmt" "knife" - "knife/middleware" + "knife/middleware/cache" + "knife/middleware/gzip" + "knife/middleware/logger" + "knife/middleware/proxy" + "knife/middleware/recover" "log" "net/http" "time" @@ -43,7 +48,7 @@ func main() { //Create a middleware chain //first plan - chain := planOne() + //chain := planOne() //second plan //chain := planTwo() @@ -51,8 +56,20 @@ func main() { //the third plan //chain := planThree() + //gzip middleware + //chain := gzipFun() + + //cache middleware + //chain := cacheFun() + + //cache middleware + chain := loadBalance() + //start serve - _ = http.ListenAndServe(":8080", chain) + err := http.ListenAndServe(":8080", chain) + if err != nil { + panic(err) + } } // plan one @@ -60,9 +77,9 @@ func planOne() *knife.Chain { //create middleware chain chain := knife.NewChain() //add logger middleware - chain.Use(middleware.Logger()) + chain.Use(logger.Logger()) //add recover middleware - chain.Use(middleware.Recover()) + chain.Use(recover.Recover()) //add custom implemented middleware chain.Use(func(context *knife.Context) { @@ -80,7 +97,7 @@ func planOne() *knife.Chain { // add middleware to the constructor func planTwo() *knife.Chain { //create a middleware chain and add logging and error handling middleware - chain := knife.NewChain(middleware.Logger(), middleware.Recover()) + chain := knife.NewChain(logger.Logger(), recover.Recover()) //add custom implemented middleware chain.Use(func(context *knife.Context) { @@ -99,8 +116,8 @@ func planTwo() *knife.Chain { func planThree() *knife.Chain { //create a middleware chain and use the chain to add logging, error handling, and custom middleware chain := knife.NewChain(). - Use(middleware.Logger()). - Use(middleware.Recover()). + Use(logger.Logger()). + Use(recover.Recover()). Use(func(context *knife.Context) { start := time.Now() defer func() { @@ -113,6 +130,74 @@ func planThree() *knife.Chain { return chain } +func gzipFun() *knife.Chain { + chain := knife.NewChain(). + Use(logger.Logger()). + Use(recover.Recover()). + //Use(middleware.GzipDefault()). + Use(gzip.Gzip(1024)). + Use(func(context *knife.Context) { + data := "Gzip是一种压缩文件格式并且也是一个在类 Unix 上的一种文件解压缩的软件,通常指GNU计划的实现,此处的gzip代表GNU zip。" + + "也经常用来表示gzip这种文件格式。软件的作者是Jean-loup Gailly和Mark Adler。在1992年10月31日第一次公开发布,版本号0.1,1993年2月,发布了1.0版本。" + + "Gzip是一种压缩文件格式并且也是一个在类 Unix 上的一种文件解压缩的软件,通常指GNU计划的实现,此处的gzip代表GNU zip。" + + "也经常用来表示gzip这种文件格式。软件的作者是Jean-loup Gailly和Mark Adler。在1992年10月31日第一次公开发布,版本号0.1,1993年2月,发布了1.0版本。" + + "Gzip是一种压缩文件格式并且也是一个在类 Unix 上的一种文件解压缩的软件,通常指GNU计划的实现,此处的gzip代表GNU zip。" + + "也经常用来表示gzip这种文件格式。软件的作者是Jean-loup Gailly和Mark Adler。在1992年10月31日第一次公开发布,版本号0.1,1993年2月,发布了1.0版本。" + _, err := context.Writer.Write([]byte(data)) + if err != nil { + panic(fmt.Sprintf("writer data error %s", err)) + } + context.Writer.WriteHeader(http.StatusOK) + }) + return chain +} + +func cacheFun() *knife.Chain { + chain := knife.NewChain(). + Use(logger.Logger()). + Use(recover.Recover()). + Use(cache.Cache(30, 60)). + Use(func(context *knife.Context) { + data := "Hello World" + _, err := context.Writer.Write([]byte(data)) + if err != nil { + panic(fmt.Sprintf("writer data error %s", err)) + } + context.Writer.WriteHeader(http.StatusOK) + }) + return chain +} + +func loadBalance() *knife.Chain { + nodes := []*proxy.ServiceNode{ + { + Address: "127.0.0.1:8080", + Weight: 1, + }, + { + Address: "127.0.0.2:8080", + Weight: 1, + }, + { + Address: "127.0.0.3:8080", + Weight: 1, + }, + } + chain := knife.NewChain(). + Use(logger.Logger()). + Use(recover.Recover()). + Use(proxy.LoadBalanceProxy(proxy.LoadBalanceRandom, nodes)). + Use(func(context *knife.Context) { + data := "Hello World" + _, err := context.Writer.Write([]byte(data)) + if err != nil { + panic(fmt.Sprintf("writer data error %s", err)) + } + context.Abort(http.StatusOK) + }) + return chain +} + ``` diff --git a/example/base/main.go b/example/base/main.go index 942f8f1..9668f3b 100644 --- a/example/base/main.go +++ b/example/base/main.go @@ -3,7 +3,11 @@ package main import ( "fmt" "knife" - "knife/middleware" + "knife/middleware/cache" + "knife/middleware/gzip" + "knife/middleware/logger" + "knife/middleware/proxy" + "knife/middleware/recover" "log" "net/http" "time" @@ -22,10 +26,10 @@ func main() { //chain := planThree() //gzip middleware - //chain := gzip() + //chain := gzipFun() //cache middleware - //chain := cache() + //chain := cacheFun() //cache middleware chain := loadBalance() @@ -42,9 +46,9 @@ func planOne() *knife.Chain { //create middleware chain chain := knife.NewChain() //add logger middleware - chain.Use(middleware.Logger()) + chain.Use(logger.Logger()) //add recover middleware - chain.Use(middleware.Recover()) + chain.Use(recover.Recover()) //add custom implemented middleware chain.Use(func(context *knife.Context) { @@ -62,7 +66,7 @@ func planOne() *knife.Chain { // add middleware to the constructor func planTwo() *knife.Chain { //create a middleware chain and add logging and error handling middleware - chain := knife.NewChain(middleware.Logger(), middleware.Recover()) + chain := knife.NewChain(logger.Logger(), recover.Recover()) //add custom implemented middleware chain.Use(func(context *knife.Context) { @@ -81,8 +85,8 @@ func planTwo() *knife.Chain { func planThree() *knife.Chain { //create a middleware chain and use the chain to add logging, error handling, and custom middleware chain := knife.NewChain(). - Use(middleware.Logger()). - Use(middleware.Recover()). + Use(logger.Logger()). + Use(recover.Recover()). Use(func(context *knife.Context) { start := time.Now() defer func() { @@ -95,12 +99,12 @@ func planThree() *knife.Chain { return chain } -func gzip() *knife.Chain { +func gzipFun() *knife.Chain { chain := knife.NewChain(). - Use(middleware.Logger()). - Use(middleware.Recover()). - //Use(middleware.GzipDefault()). - Use(middleware.Gzip(1024)). + Use(logger.Logger()). + Use(recover.Recover()). + //Use(gzip.Default()). + Use(gzip.Gzip(1024)). Use(func(context *knife.Context) { data := "Gzip是一种压缩文件格式并且也是一个在类 Unix 上的一种文件解压缩的软件,通常指GNU计划的实现,此处的gzip代表GNU zip。" + "也经常用来表示gzip这种文件格式。软件的作者是Jean-loup Gailly和Mark Adler。在1992年10月31日第一次公开发布,版本号0.1,1993年2月,发布了1.0版本。" + @@ -117,11 +121,11 @@ func gzip() *knife.Chain { return chain } -func cache() *knife.Chain { +func cacheFun() *knife.Chain { chain := knife.NewChain(). - Use(middleware.Logger()). - Use(middleware.Recover()). - Use(middleware.Cache(30, 60)). + Use(logger.Logger()). + Use(recover.Recover()). + Use(cache.Cache(30, 60)). Use(func(context *knife.Context) { data := "Hello World" _, err := context.Writer.Write([]byte(data)) @@ -134,7 +138,7 @@ func cache() *knife.Chain { } func loadBalance() *knife.Chain { - nodes := []*middleware.ServiceNode{ + nodes := []*proxy.ServiceNode{ { Address: "127.0.0.1:8080", Weight: 1, @@ -149,9 +153,9 @@ func loadBalance() *knife.Chain { }, } chain := knife.NewChain(). - Use(middleware.Logger()). - Use(middleware.Recover()). - Use(middleware.LoadBalanceProxy(middleware.LoadBalanceRandom, nodes)). + Use(logger.Logger()). + Use(recover.Recover()). + Use(proxy.LoadBalanceProxy(proxy.LoadBalanceRandom, nodes)). Use(func(context *knife.Context) { data := "Hello World" _, err := context.Writer.Write([]byte(data)) diff --git a/example/matcher/main.go b/example/matcher/main.go index f6dbe3e..6019662 100644 --- a/example/matcher/main.go +++ b/example/matcher/main.go @@ -2,8 +2,11 @@ package main import ( "knife" - "knife/matcher" - "knife/middleware" + "knife/matcher/combination" + "knife/matcher/header" + "knife/matcher/path" + "knife/middleware/logger" + "knife/middleware/recover" "log" "net/http" ) @@ -13,24 +16,24 @@ func main() { //创建中间件链 chain := knife.NewChain() //添加日志记录中间件 - chain.Use(middleware.Logger()) + chain.Use(logger.Logger()) //添加错误处理中间件 - chain.Use(middleware.Recover()) + chain.Use(recover.Recover()) //添加响应头是否存在匹配器的自定义中间件 - chain.UseMatcher(matcher.HeaderResponseExists("token"), func(context *knife.Context) { + chain.UseMatcher(header.ResponseExists("token"), func(context *knife.Context) { log.Printf("token middleware,token:%s ", context.Writer.Header().Get("token")) context.Next() }) //添加带有组合匹配器的自定义中间件 - chain.UseMatcher(matcher.Any(matcher.HeaderResponseExists("token"), matcher.HeaderResponseExists("auth")), func(context *knife.Context) { + chain.UseMatcher(combination.Any(header.ResponseExists("token"), header.ResponseExists("auth")), func(context *knife.Context) { log.Printf("token middleware,token:%s ", context.Writer.Header().Get("token")) context.Next() }) //添加带路径匹配器的自定义中间件 - chain.UseMatcher(matcher.PathPrefix("/hello"), func(context *knife.Context) { + chain.UseMatcher(path.Prefix("/hello"), func(context *knife.Context) { log.Println("pathPrefix matcher") context.Next() }) diff --git a/knife/matcher/combination.go b/knife/matcher/combination/combination.go similarity index 97% rename from knife/matcher/combination.go rename to knife/matcher/combination/combination.go index c9e3ffb..b756f15 100644 --- a/knife/matcher/combination.go +++ b/knife/matcher/combination/combination.go @@ -1,6 +1,6 @@ // 将匹配器进行组合的匹配器 -package matcher +package combination import "knife" diff --git a/knife/matcher/header.go b/knife/matcher/header/header.go similarity index 77% rename from knife/matcher/header.go rename to knife/matcher/header/header.go index fe52d04..88f0981 100644 --- a/knife/matcher/header.go +++ b/knife/matcher/header/header.go @@ -1,43 +1,43 @@ // 关于请求头的匹配器 -package matcher +package header import ( "knife" "net/http" ) -func HeaderResponseExists(key string) knife.MiddlewareMatcher { +func ResponseExists(key string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return !equalHeaderValue(response.Header(), key, "") } } -func HeaderResponseNotExists(key string) knife.MiddlewareMatcher { +func ResponseNotExists(key string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return equalHeaderValue(response.Header(), key, "") } } -func HeaderResponseNe(key, value string) knife.MiddlewareMatcher { +func ResponseNe(key, value string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return !equalHeaderValue(response.Header(), key, value) } } -func HeaderResponseEq(key, value string) knife.MiddlewareMatcher { +func ResponseEq(key, value string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return equalHeaderValue(response.Header(), key, value) } } -func HeaderRequestExists(key string) knife.MiddlewareMatcher { +func RequestExists(key string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return !equalHeaderValue(request.Header, key, "") } } -func HeaderRequestNotExists(key string) knife.MiddlewareMatcher { +func RequestNotExists(key string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return equalHeaderValue(request.Header, key, "") } diff --git a/knife/matcher/method.go b/knife/matcher/method/method.go similarity index 76% rename from knife/matcher/method.go rename to knife/matcher/method/method.go index fbe3bdd..402680a 100644 --- a/knife/matcher/method.go +++ b/knife/matcher/method/method.go @@ -1,26 +1,26 @@ // 关于请求方法的匹配器 -package matcher +package method import ( "knife" "strings" ) -func MethodEq(method string) knife.MiddlewareMatcher { +func Eq(method string) knife.MiddlewareMatcher { method = strings.ToUpper(method) return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return request.Method == method } } -func MethodNe(method string) knife.MiddlewareMatcher { +func Ne(method string) knife.MiddlewareMatcher { method = strings.ToUpper(method) return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return request.Method != method } } -func MethodAny(methods ...string) knife.MiddlewareMatcher { +func Any(methods ...string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { for _, method := range methods { method = strings.ToUpper(method) diff --git a/knife/matcher/path.go b/knife/matcher/path/path.go similarity index 79% rename from knife/matcher/path.go rename to knife/matcher/path/path.go index 9f911d9..c00d0a6 100644 --- a/knife/matcher/path.go +++ b/knife/matcher/path/path.go @@ -1,6 +1,6 @@ // 关于路径的匹配器 -package matcher +package path import ( "fmt" @@ -10,15 +10,15 @@ import ( "strings" ) -// PathPrefix 路径前缀匹配 -func PathPrefix(prefix string) knife.MiddlewareMatcher { +// Prefix 路径前缀匹配 +func Prefix(prefix string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { return strings.HasPrefix(request.URL.Path, prefix) } } -// PathMatch 路径正则匹配 -func PathMatch(pattern string) knife.MiddlewareMatcher { +// Match 路径正则匹配 +func Match(pattern string) knife.MiddlewareMatcher { return func(response knife.HttpResponseWriter, request knife.HttpRequest) bool { matched, err := isPathMatched(request.URL.Path, pattern) if err != nil { diff --git a/knife/middleware/cache.go b/knife/middleware/cache/cache.go similarity index 99% rename from knife/middleware/cache.go rename to knife/middleware/cache/cache.go index e9a9ebc..232a742 100644 --- a/knife/middleware/cache.go +++ b/knife/middleware/cache/cache.go @@ -1,4 +1,4 @@ -package middleware +package cache import ( "fmt" diff --git a/knife/middleware/gzip.go b/knife/middleware/gzip/gzip.go similarity index 92% rename from knife/middleware/gzip.go rename to knife/middleware/gzip/gzip.go index 5bd47b8..5a572c1 100644 --- a/knife/middleware/gzip.go +++ b/knife/middleware/gzip/gzip.go @@ -1,4 +1,4 @@ -package middleware +package gzip import ( "bytes" @@ -6,8 +6,8 @@ import ( "knife" ) -// GzipDefault 当响应体的大小超过100kb后,进行gzip压缩 -func GzipDefault() knife.MiddlewareFunc { +// Default 当响应体的大小超过100kb后,进行gzip压缩 +func Default() knife.MiddlewareFunc { return Gzip(100 * 1024) } diff --git a/knife/middleware/logger.go b/knife/middleware/logger/logger.go similarity index 96% rename from knife/middleware/logger.go rename to knife/middleware/logger/logger.go index 2a037e4..75f9d17 100644 --- a/knife/middleware/logger.go +++ b/knife/middleware/logger/logger.go @@ -1,4 +1,4 @@ -package middleware +package logger import ( "knife" diff --git a/knife/middleware/load_balance_proxy.go b/knife/middleware/proxy/load_balance_proxy.go similarity index 99% rename from knife/middleware/load_balance_proxy.go rename to knife/middleware/proxy/load_balance_proxy.go index 66b629d..74a0fb2 100644 --- a/knife/middleware/load_balance_proxy.go +++ b/knife/middleware/proxy/load_balance_proxy.go @@ -1,4 +1,4 @@ -package middleware +package proxy import ( "fmt" diff --git a/knife/middleware/load_balance_proxy_test.go b/knife/middleware/proxy/load_balance_proxy_test.go similarity index 99% rename from knife/middleware/load_balance_proxy_test.go rename to knife/middleware/proxy/load_balance_proxy_test.go index bb8d7d2..1119de3 100644 --- a/knife/middleware/load_balance_proxy_test.go +++ b/knife/middleware/proxy/load_balance_proxy_test.go @@ -1,4 +1,4 @@ -package middleware +package proxy import ( "github.com/stretchr/testify/assert" diff --git a/knife/middleware/proxy.go b/knife/middleware/proxy/proxy.go similarity index 99% rename from knife/middleware/proxy.go rename to knife/middleware/proxy/proxy.go index be52f32..54743fc 100644 --- a/knife/middleware/proxy.go +++ b/knife/middleware/proxy/proxy.go @@ -1,4 +1,4 @@ -package middleware +package proxy import ( "knife" diff --git a/knife/middleware/recover.go b/knife/middleware/recover/recover.go similarity index 99% rename from knife/middleware/recover.go rename to knife/middleware/recover/recover.go index 0a5d18f..8da664f 100644 --- a/knife/middleware/recover.go +++ b/knife/middleware/recover/recover.go @@ -1,4 +1,4 @@ -package middleware +package recover import ( "bytes" diff --git a/knife/middleware/strip_prefix.go b/knife/middleware/stripprefix/strip_prefix.go similarity index 90% rename from knife/middleware/strip_prefix.go rename to knife/middleware/stripprefix/strip_prefix.go index ee6529e..0e503bd 100644 --- a/knife/middleware/strip_prefix.go +++ b/knife/middleware/stripprefix/strip_prefix.go @@ -1,4 +1,4 @@ -package middleware +package stripprefix import ( "knife" @@ -6,6 +6,7 @@ import ( "strings" ) +// StripPrefix 剥离前缀 func StripPrefix(prefix string) knife.MiddlewareFunc { return func(context *knife.Context) { r := context.Req