first commit
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Gin-Gonic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
# GZIP gin's middleware
|
||||
|
||||
Gin middleware to enable `GZIP` support.
|
||||
|
||||
Copied from [gin-contrib/gzip](https://github.com/gin-contrib/gzip)
|
||||
|
||||
## Usage
|
||||
|
||||
Canonical example:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gitverse.ru/andoma/gin-contrib/gzip"
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
|
||||
})
|
||||
|
||||
// Listen and Server in 0.0.0.0:8080
|
||||
if err := r.Run(":8080"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Customized Excluded Extensions
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gitverse.ru/andoma/gin-contrib/gzip"
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedExtensions([]string{".pdf", ".mp4"})))
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
|
||||
})
|
||||
|
||||
// Listen and Server in 0.0.0.0:8080
|
||||
if err := r.Run(":8080"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Customized Excluded Paths
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gitverse.ru/andoma/gin-contrib/gzip"
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedPaths([]string{"/api/"})))
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
|
||||
})
|
||||
|
||||
// Listen and Server in 0.0.0.0:8080
|
||||
if err := r.Run(":8080"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Customized Excluded Paths
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gitverse.ru/andoma/gin-contrib/gzip"
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := gin.Default()
|
||||
r.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedPathsRegexs([]string{".*"})))
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
|
||||
})
|
||||
|
||||
// Listen and Server in 0.0.0.0:8080
|
||||
if err := r.Run(":8080"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
package gzip
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
BestCompression = gzip.BestCompression
|
||||
BestSpeed = gzip.BestSpeed
|
||||
DefaultCompression = gzip.DefaultCompression
|
||||
NoCompression = gzip.NoCompression
|
||||
)
|
||||
|
||||
func Gzip(level int, options ...Option) gin.HandlerFunc {
|
||||
return newGzipHandler(level, options...).Handle
|
||||
}
|
||||
|
||||
type gzipWriter struct {
|
||||
gin.ResponseWriter
|
||||
writer *gzip.Writer
|
||||
}
|
||||
|
||||
func (g *gzipWriter) WriteString(s string) (int, error) {
|
||||
g.Header().Del("Content-Length")
|
||||
return g.writer.Write([]byte(s))
|
||||
}
|
||||
|
||||
func (g *gzipWriter) Write(data []byte) (int, error) {
|
||||
g.Header().Del("Content-Length")
|
||||
return g.writer.Write(data)
|
||||
}
|
||||
|
||||
// Fix: https://github.com/mholt/caddy/issues/38
|
||||
func (g *gzipWriter) WriteHeader(code int) {
|
||||
g.Header().Del("Content-Length")
|
||||
g.ResponseWriter.WriteHeader(code)
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
package gzip
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
testResponse = "Gzip Test Response "
|
||||
testReverseResponse = "Gzip Test Reverse Response "
|
||||
)
|
||||
|
||||
type rServer struct{}
|
||||
|
||||
func (s *rServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
fmt.Fprint(rw, testReverseResponse)
|
||||
}
|
||||
|
||||
type closeNotifyingRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
closed chan bool
|
||||
}
|
||||
|
||||
func newCloseNotifyingRecorder() *closeNotifyingRecorder {
|
||||
return &closeNotifyingRecorder{
|
||||
httptest.NewRecorder(),
|
||||
make(chan bool, 1),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *closeNotifyingRecorder) CloseNotify() <-chan bool {
|
||||
return c.closed
|
||||
}
|
||||
|
||||
func newServer() *gin.Engine {
|
||||
// init reverse proxy server
|
||||
rServer := httptest.NewServer(new(rServer))
|
||||
target, _ := url.Parse(rServer.URL)
|
||||
rp := httputil.NewSingleHostReverseProxy(target)
|
||||
|
||||
router := gin.New()
|
||||
router.Use(Gzip(DefaultCompression))
|
||||
router.GET("/", func(c *gin.Context) {
|
||||
c.Header("Content-Length", strconv.Itoa(len(testResponse)))
|
||||
c.String(200, testResponse)
|
||||
})
|
||||
router.Any("/reverse", func(c *gin.Context) {
|
||||
rp.ServeHTTP(c.Writer, c.Request)
|
||||
})
|
||||
return router
|
||||
}
|
||||
|
||||
func TestGzip(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "GET", "/", nil)
|
||||
req.Header.Add("Accept-Encoding", "gzip")
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r := newServer()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, w.Code, 200)
|
||||
assert.Equal(t, w.Header().Get("Content-Encoding"), "gzip")
|
||||
assert.Equal(t, w.Header().Get("Vary"), "Accept-Encoding")
|
||||
assert.NotEqual(t, w.Header().Get("Content-Length"), "0")
|
||||
assert.NotEqual(t, w.Body.Len(), 19)
|
||||
assert.Equal(t, fmt.Sprint(w.Body.Len()), w.Header().Get("Content-Length"))
|
||||
|
||||
gr, err := gzip.NewReader(w.Body)
|
||||
assert.NoError(t, err)
|
||||
defer gr.Close()
|
||||
|
||||
body, _ := io.ReadAll(gr)
|
||||
assert.Equal(t, string(body), testResponse)
|
||||
}
|
||||
|
||||
func TestGzipPNG(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "GET", "/image.png", nil)
|
||||
req.Header.Add("Accept-Encoding", "gzip")
|
||||
|
||||
router := gin.New()
|
||||
router.Use(Gzip(DefaultCompression))
|
||||
router.GET("/image.png", func(c *gin.Context) {
|
||||
c.String(200, "this is a PNG!")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, w.Code, 200)
|
||||
assert.Equal(t, w.Header().Get("Content-Encoding"), "")
|
||||
assert.Equal(t, w.Header().Get("Vary"), "")
|
||||
assert.Equal(t, w.Body.String(), "this is a PNG!")
|
||||
}
|
||||
|
||||
func TestExcludedExtensions(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "GET", "/index.html", nil)
|
||||
req.Header.Add("Accept-Encoding", "gzip")
|
||||
|
||||
router := gin.New()
|
||||
router.Use(Gzip(DefaultCompression, WithExcludedExtensions([]string{".html"})))
|
||||
router.GET("/index.html", func(c *gin.Context) {
|
||||
c.String(200, "this is a HTML!")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "", w.Header().Get("Content-Encoding"))
|
||||
assert.Equal(t, "", w.Header().Get("Vary"))
|
||||
assert.Equal(t, "this is a HTML!", w.Body.String())
|
||||
assert.Equal(t, "", w.Header().Get("Content-Length"))
|
||||
}
|
||||
|
||||
func TestExcludedPaths(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "GET", "/api/books", nil)
|
||||
req.Header.Add("Accept-Encoding", "gzip")
|
||||
|
||||
router := gin.New()
|
||||
router.Use(Gzip(DefaultCompression, WithExcludedPaths([]string{"/api/"})))
|
||||
router.GET("/api/books", func(c *gin.Context) {
|
||||
c.String(200, "this is books!")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "", w.Header().Get("Content-Encoding"))
|
||||
assert.Equal(t, "", w.Header().Get("Vary"))
|
||||
assert.Equal(t, "this is books!", w.Body.String())
|
||||
assert.Equal(t, "", w.Header().Get("Content-Length"))
|
||||
}
|
||||
|
||||
func TestNoGzip(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "GET", "/", nil)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r := newServer()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, w.Code, 200)
|
||||
assert.Equal(t, w.Header().Get("Content-Encoding"), "")
|
||||
assert.Equal(t, w.Header().Get("Content-Length"), "19")
|
||||
assert.Equal(t, w.Body.String(), testResponse)
|
||||
}
|
||||
|
||||
func TestGzipWithReverseProxy(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "GET", "/reverse", nil)
|
||||
req.Header.Add("Accept-Encoding", "gzip")
|
||||
|
||||
w := newCloseNotifyingRecorder()
|
||||
r := newServer()
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, w.Code, 200)
|
||||
assert.Equal(t, w.Header().Get("Content-Encoding"), "gzip")
|
||||
assert.Equal(t, w.Header().Get("Vary"), "Accept-Encoding")
|
||||
assert.NotEqual(t, w.Header().Get("Content-Length"), "0")
|
||||
assert.NotEqual(t, w.Body.Len(), 19)
|
||||
assert.Equal(t, fmt.Sprint(w.Body.Len()), w.Header().Get("Content-Length"))
|
||||
|
||||
gr, err := gzip.NewReader(w.Body)
|
||||
assert.NoError(t, err)
|
||||
defer gr.Close()
|
||||
|
||||
body, _ := io.ReadAll(gr)
|
||||
assert.Equal(t, string(body), testReverseResponse)
|
||||
}
|
||||
|
||||
func TestDecompressGzip(t *testing.T) {
|
||||
buf := &bytes.Buffer{}
|
||||
gz, _ := gzip.NewWriterLevel(buf, gzip.DefaultCompression)
|
||||
if _, err := gz.Write([]byte(testResponse)); err != nil {
|
||||
gz.Close()
|
||||
t.Fatal(err)
|
||||
}
|
||||
gz.Close()
|
||||
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "POST", "/", buf)
|
||||
req.Header.Add("Content-Encoding", "gzip")
|
||||
|
||||
router := gin.New()
|
||||
router.Use(Gzip(DefaultCompression, WithDecompressFn(DefaultDecompressHandle)))
|
||||
router.POST("/", func(c *gin.Context) {
|
||||
if v := c.Request.Header.Get("Content-Encoding"); v != "" {
|
||||
t.Errorf("unexpected `Content-Encoding`: %s header", v)
|
||||
}
|
||||
if v := c.Request.Header.Get("Content-Length"); v != "" {
|
||||
t.Errorf("unexpected `Content-Length`: %s header", v)
|
||||
}
|
||||
data, err := c.GetRawData()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
c.Data(200, "text/plain", data)
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "", w.Header().Get("Content-Encoding"))
|
||||
assert.Equal(t, "", w.Header().Get("Vary"))
|
||||
assert.Equal(t, testResponse, w.Body.String())
|
||||
assert.Equal(t, "", w.Header().Get("Content-Length"))
|
||||
}
|
||||
|
||||
func TestDecompressGzipWithEmptyBody(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "POST", "/", nil)
|
||||
req.Header.Add("Content-Encoding", "gzip")
|
||||
|
||||
router := gin.New()
|
||||
router.Use(Gzip(DefaultCompression, WithDecompressFn(DefaultDecompressHandle)))
|
||||
router.POST("/", func(c *gin.Context) {
|
||||
c.String(200, "ok")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "", w.Header().Get("Content-Encoding"))
|
||||
assert.Equal(t, "", w.Header().Get("Vary"))
|
||||
assert.Equal(t, "ok", w.Body.String())
|
||||
assert.Equal(t, "", w.Header().Get("Content-Length"))
|
||||
}
|
||||
|
||||
func TestDecompressGzipWithIncorrectData(t *testing.T) {
|
||||
req, _ := http.NewRequestWithContext(context.Background(), "POST", "/", bytes.NewReader([]byte(testResponse)))
|
||||
req.Header.Add("Content-Encoding", "gzip")
|
||||
|
||||
router := gin.New()
|
||||
router.Use(Gzip(DefaultCompression, WithDecompressFn(DefaultDecompressHandle)))
|
||||
router.POST("/", func(c *gin.Context) {
|
||||
c.String(200, "ok")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package gzip
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
type gzipHandler struct {
|
||||
*Options
|
||||
gzPool sync.Pool
|
||||
}
|
||||
|
||||
func newGzipHandler(level int, options ...Option) *gzipHandler {
|
||||
handler := &gzipHandler{
|
||||
Options: DefaultOptions,
|
||||
gzPool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
gz, err := gzip.NewWriterLevel(io.Discard, level)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return gz
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, setter := range options {
|
||||
setter(handler.Options)
|
||||
}
|
||||
return handler
|
||||
}
|
||||
|
||||
func (g *gzipHandler) Handle(c *gin.Context) {
|
||||
if fn := g.DecompressFn; fn != nil && c.Request.Header.Get("Content-Encoding") == "gzip" {
|
||||
fn(c)
|
||||
}
|
||||
|
||||
if !g.shouldCompress(c.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
gz := g.gzPool.Get().(*gzip.Writer)
|
||||
defer g.gzPool.Put(gz)
|
||||
defer gz.Reset(io.Discard)
|
||||
gz.Reset(c.Writer)
|
||||
|
||||
c.Header("Content-Encoding", "gzip")
|
||||
c.Header("Vary", "Accept-Encoding")
|
||||
c.Writer = &gzipWriter{c.Writer, gz}
|
||||
defer func() {
|
||||
gz.Close()
|
||||
c.Header("Content-Length", fmt.Sprint(c.Writer.Size()))
|
||||
}()
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func (g *gzipHandler) shouldCompress(req *http.Request) bool {
|
||||
if !strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") ||
|
||||
strings.Contains(req.Header.Get("Connection"), "Upgrade") ||
|
||||
strings.Contains(req.Header.Get("Accept"), "text/event-stream") {
|
||||
return false
|
||||
}
|
||||
|
||||
extension := filepath.Ext(req.URL.Path)
|
||||
if g.ExcludedExtensions.Contains(extension) {
|
||||
return false
|
||||
}
|
||||
|
||||
if g.ExcludedPaths.Contains(req.URL.Path) {
|
||||
return false
|
||||
}
|
||||
if g.ExcludedPathesRegexs.Contains(req.URL.Path) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package gzip
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gitverse.ru/andoma/gin"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultExcludedExtentions = NewExcludedExtensions([]string{
|
||||
".png", ".gif", ".jpeg", ".jpg",
|
||||
})
|
||||
DefaultOptions = &Options{
|
||||
ExcludedExtensions: DefaultExcludedExtentions,
|
||||
}
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
ExcludedExtensions ExcludedExtensions
|
||||
ExcludedPaths ExcludedPaths
|
||||
ExcludedPathesRegexs ExcludedPathesRegexs
|
||||
DecompressFn func(c *gin.Context)
|
||||
}
|
||||
|
||||
type Option func(*Options)
|
||||
|
||||
func WithExcludedExtensions(args []string) Option {
|
||||
return func(o *Options) {
|
||||
o.ExcludedExtensions = NewExcludedExtensions(args)
|
||||
}
|
||||
}
|
||||
|
||||
func WithExcludedPaths(args []string) Option {
|
||||
return func(o *Options) {
|
||||
o.ExcludedPaths = NewExcludedPaths(args)
|
||||
}
|
||||
}
|
||||
|
||||
func WithExcludedPathsRegexs(args []string) Option {
|
||||
return func(o *Options) {
|
||||
o.ExcludedPathesRegexs = NewExcludedPathesRegexs(args)
|
||||
}
|
||||
}
|
||||
|
||||
func WithDecompressFn(decompressFn func(c *gin.Context)) Option {
|
||||
return func(o *Options) {
|
||||
o.DecompressFn = decompressFn
|
||||
}
|
||||
}
|
||||
|
||||
// Using map for better lookup performance
|
||||
type ExcludedExtensions map[string]bool
|
||||
|
||||
func NewExcludedExtensions(extensions []string) ExcludedExtensions {
|
||||
res := make(ExcludedExtensions)
|
||||
for _, e := range extensions {
|
||||
res[e] = true
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (e ExcludedExtensions) Contains(target string) bool {
|
||||
_, ok := e[target]
|
||||
return ok
|
||||
}
|
||||
|
||||
type ExcludedPaths []string
|
||||
|
||||
func NewExcludedPaths(paths []string) ExcludedPaths {
|
||||
return ExcludedPaths(paths)
|
||||
}
|
||||
|
||||
func (e ExcludedPaths) Contains(requestURI string) bool {
|
||||
for _, path := range e {
|
||||
if strings.HasPrefix(requestURI, path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ExcludedPathesRegexs []*regexp.Regexp
|
||||
|
||||
func NewExcludedPathesRegexs(regexs []string) ExcludedPathesRegexs {
|
||||
result := make([]*regexp.Regexp, len(regexs))
|
||||
for i, reg := range regexs {
|
||||
result[i] = regexp.MustCompile(reg)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e ExcludedPathesRegexs) Contains(requestURI string) bool {
|
||||
for _, reg := range e {
|
||||
if reg.MatchString(requestURI) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func DefaultDecompressHandle(c *gin.Context) {
|
||||
if c.Request.Body == nil {
|
||||
return
|
||||
}
|
||||
r, err := gzip.NewReader(c.Request.Body)
|
||||
if err != nil {
|
||||
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
c.Request.Header.Del("Content-Encoding")
|
||||
c.Request.Header.Del("Content-Length")
|
||||
c.Request.Body = r
|
||||
}
|
||||
Reference in New Issue
Block a user