...

Source file src/github.com/gin-gonic/contrib/gzip/gzip.go

Documentation: github.com/gin-gonic/contrib/gzip

     1  package gzip
     2  
     3  import (
     4  	"compress/gzip"
     5  	"net/http"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/gin-gonic/gin"
    10  )
    11  
    12  const (
    13  	BestCompression    = gzip.BestCompression
    14  	BestSpeed          = gzip.BestSpeed
    15  	DefaultCompression = gzip.DefaultCompression
    16  	NoCompression      = gzip.NoCompression
    17  )
    18  
    19  func Gzip(level int) gin.HandlerFunc {
    20  	return func(c *gin.Context) {
    21  		if !shouldCompress(c.Request) {
    22  			return
    23  		}
    24  		gz, err := gzip.NewWriterLevel(c.Writer, level)
    25  		if err != nil {
    26  			return
    27  		}
    28  
    29  		c.Header("Content-Encoding", "gzip")
    30  		c.Header("Vary", "Accept-Encoding")
    31  		c.Writer = &gzipWriter{c.Writer, gz}
    32  		defer func() {
    33  			c.Header("Content-Length", "0")
    34  			gz.Close()
    35  		}()
    36  		c.Next()
    37  	}
    38  }
    39  
    40  type gzipWriter struct {
    41  	gin.ResponseWriter
    42  	writer *gzip.Writer
    43  }
    44  
    45  func (g *gzipWriter) WriteString(s string) (int, error) {
    46  	return g.writer.Write([]byte(s))
    47  }
    48  
    49  func (g *gzipWriter) Write(data []byte) (int, error) {
    50  	return g.writer.Write(data)
    51  }
    52  
    53  func shouldCompress(req *http.Request) bool {
    54  	if !strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
    55  		return false
    56  	}
    57  	extension := filepath.Ext(req.URL.Path)
    58  	if len(extension) < 4 { // fast path
    59  		return true
    60  	}
    61  
    62  	switch extension {
    63  	case ".png", ".gif", ".jpeg", ".jpg":
    64  		return false
    65  	default:
    66  		return true
    67  	}
    68  }
    69  

View as plain text