| package middleware |
|
|
| import ( |
| "compress/gzip" |
| "io" |
| "net/http" |
|
|
| "github.com/QuantumNous/new-api/constant" |
| "github.com/andybalholm/brotli" |
| "github.com/gin-gonic/gin" |
| ) |
|
|
| type readCloser struct { |
| io.Reader |
| closeFn func() error |
| } |
|
|
| func (rc *readCloser) Close() error { |
| if rc.closeFn != nil { |
| return rc.closeFn() |
| } |
| return nil |
| } |
|
|
| func DecompressRequestMiddleware() gin.HandlerFunc { |
| return func(c *gin.Context) { |
| if c.Request.Body == nil || c.Request.Method == http.MethodGet { |
| c.Next() |
| return |
| } |
| maxMB := constant.MaxRequestBodyMB |
| if maxMB <= 0 { |
| maxMB = 32 |
| } |
| maxBytes := int64(maxMB) << 20 |
|
|
| origBody := c.Request.Body |
| wrapMaxBytes := func(body io.ReadCloser) io.ReadCloser { |
| return http.MaxBytesReader(c.Writer, body, maxBytes) |
| } |
|
|
| switch c.GetHeader("Content-Encoding") { |
| case "gzip": |
| gzipReader, err := gzip.NewReader(origBody) |
| if err != nil { |
| _ = origBody.Close() |
| c.AbortWithStatus(http.StatusBadRequest) |
| return |
| } |
| |
| c.Request.Body = wrapMaxBytes(&readCloser{ |
| Reader: gzipReader, |
| closeFn: func() error { |
| _ = gzipReader.Close() |
| return origBody.Close() |
| }, |
| }) |
| c.Request.Header.Del("Content-Encoding") |
| case "br": |
| reader := brotli.NewReader(origBody) |
| c.Request.Body = wrapMaxBytes(&readCloser{ |
| Reader: reader, |
| closeFn: func() error { |
| return origBody.Close() |
| }, |
| }) |
| c.Request.Header.Del("Content-Encoding") |
| default: |
| |
| c.Request.Body = wrapMaxBytes(origBody) |
| } |
|
|
| |
| c.Next() |
| } |
| } |
|
|