diff --git a/go.mod b/go.mod index 842a72b..5972d7d 100644 --- a/go.mod +++ b/go.mod @@ -2,3 +2,10 @@ module source.toby3d.me/toby3d/middleware go 1.17 +require github.com/valyala/fasthttp v1.31.0 + +require ( + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..436f1c4 --- /dev/null +++ b/go.sum @@ -0,0 +1,24 @@ +github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E= +github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s= +github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.31.0 h1:lrauRLII19afgCs2fnWRJ4M5IkV0lo2FqA61uGkNBfE= +github.com/valyala/fasthttp v1.31.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/middleware.go b/middleware.go new file mode 100644 index 0000000..a16683e --- /dev/null +++ b/middleware.go @@ -0,0 +1,49 @@ +// Package middleware provides methods to analyze and mutate data delivered over +// HTTP. +package middleware + +import http "github.com/valyala/fasthttp" + +type ( + // BeforeFunc is an alias of fasthttp.RequestHandler to execute its own + // logic before middleware. + BeforeFunc = http.RequestHandler + + // Chain describes the middlewares call chain. + Chain []Interceptor + + // Interceptor describes the middleware contract. + Interceptor func(*http.RequestCtx, http.RequestHandler) + + // RequestHandler is an alias of fasthttp.RequestHandler for the + // extension. + RequestHandler http.RequestHandler + + // Skipper defines a function to skip middleware. Returning true skips + // processing the middleware. + Skipper func(*http.RequestCtx) bool +) + +// DefaultSkipper is the default skipper, which always returns false. +//nolint: gochecknoglobals +var DefaultSkipper Skipper = func(*http.RequestCtx) bool { return false } + +// Intercept wraps the RequestHandler in middleware input. +func (count RequestHandler) Intercept(middleware Interceptor) RequestHandler { + return func(ctx *http.RequestCtx) { + middleware(ctx, http.RequestHandler(count)) + } +} + +// RequestHandler wraps the input into the middlewares chain starting from the +// last to first and returns fasthttp.RequestHandler. +func (chain Chain) RequestHandler(handler http.RequestHandler) http.RequestHandler { + current := RequestHandler(handler) + + for i := len(chain) - 1; i >= 0; i-- { + m := chain[i] + current = current.Intercept(m) + } + + return http.RequestHandler(current) +}