mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-09-10 23:32:30 +00:00
.github
bridge
ci
contrib
docker
gateway
hook
img
matterclient
matterhook
vendor
github.com
42wim
Jeffail
Philipp15b
bwmarrin
davecgh
dfordsoft
dgrijalva
fsnotify
go-telegram-bot-api
golang
google
gopackage
gorilla
hashicorp
jpillora
kardianos
konsorten
labstack
echo
v4
middleware
basic_auth.go
body_dump.go
body_limit.go
compress.go
cors.go
csrf.go
jwt.go
key_auth.go
logger.go
method_override.go
middleware.go
proxy.go
proxy_1_11.go
proxy_1_11_n.go
recover.go
redirect.go
request_id.go
rewrite.go
secure.go
slash.go
static.go
.editorconfig
.gitattributes
.gitignore
.travis.yml
LICENSE
Makefile
README.md
bind.go
context.go
echo.go
go.mod
go.sum
group.go
log.go
response.go
router.go
gommon
lrstanley
magiconair
matterbridge
mattermost
mattn
mgutz
mitchellh
mreiferson
mrexodia
nelsonken
nicksnyder
nlopes
paulrosania
pborman
pelletier
peterhellberg
pkg
pmezard
rs
russross
saintfish
shazow
shurcooL
sirupsen
spf13
stretchr
technoweenie
valyala
zfjagann
gitlab.com
go.uber.org
golang.org
gopkg.in
modules.txt
.golangci.yaml
.travis.yml
Dockerfile
LICENSE
README.md
changelog.md
go.mod
go.sum
matterbridge.go
matterbridge.toml.sample
matterbridge.toml.simple
119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package middleware
|
|
|
|
import (
|
|
"bufio"
|
|
"compress/gzip"
|
|
"io"
|
|
"io/ioutil"
|
|
"net"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
type (
|
|
// GzipConfig defines the config for Gzip middleware.
|
|
GzipConfig struct {
|
|
// Skipper defines a function to skip middleware.
|
|
Skipper Skipper
|
|
|
|
// Gzip compression level.
|
|
// Optional. Default value -1.
|
|
Level int `yaml:"level"`
|
|
}
|
|
|
|
gzipResponseWriter struct {
|
|
io.Writer
|
|
http.ResponseWriter
|
|
}
|
|
)
|
|
|
|
const (
|
|
gzipScheme = "gzip"
|
|
)
|
|
|
|
var (
|
|
// DefaultGzipConfig is the default Gzip middleware config.
|
|
DefaultGzipConfig = GzipConfig{
|
|
Skipper: DefaultSkipper,
|
|
Level: -1,
|
|
}
|
|
)
|
|
|
|
// Gzip returns a middleware which compresses HTTP response using gzip compression
|
|
// scheme.
|
|
func Gzip() echo.MiddlewareFunc {
|
|
return GzipWithConfig(DefaultGzipConfig)
|
|
}
|
|
|
|
// GzipWithConfig return Gzip middleware with config.
|
|
// See: `Gzip()`.
|
|
func GzipWithConfig(config GzipConfig) echo.MiddlewareFunc {
|
|
// Defaults
|
|
if config.Skipper == nil {
|
|
config.Skipper = DefaultGzipConfig.Skipper
|
|
}
|
|
if config.Level == 0 {
|
|
config.Level = DefaultGzipConfig.Level
|
|
}
|
|
|
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
if config.Skipper(c) {
|
|
return next(c)
|
|
}
|
|
|
|
res := c.Response()
|
|
res.Header().Add(echo.HeaderVary, echo.HeaderAcceptEncoding)
|
|
if strings.Contains(c.Request().Header.Get(echo.HeaderAcceptEncoding), gzipScheme) {
|
|
res.Header().Set(echo.HeaderContentEncoding, gzipScheme) // Issue #806
|
|
rw := res.Writer
|
|
w, err := gzip.NewWriterLevel(rw, config.Level)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if res.Size == 0 {
|
|
if res.Header().Get(echo.HeaderContentEncoding) == gzipScheme {
|
|
res.Header().Del(echo.HeaderContentEncoding)
|
|
}
|
|
// We have to reset response to it's pristine state when
|
|
// nothing is written to body or error is returned.
|
|
// See issue #424, #407.
|
|
res.Writer = rw
|
|
w.Reset(ioutil.Discard)
|
|
}
|
|
w.Close()
|
|
}()
|
|
grw := &gzipResponseWriter{Writer: w, ResponseWriter: rw}
|
|
res.Writer = grw
|
|
}
|
|
return next(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (w *gzipResponseWriter) WriteHeader(code int) {
|
|
if code == http.StatusNoContent { // Issue #489
|
|
w.ResponseWriter.Header().Del(echo.HeaderContentEncoding)
|
|
}
|
|
w.Header().Del(echo.HeaderContentLength) // Issue #444
|
|
w.ResponseWriter.WriteHeader(code)
|
|
}
|
|
|
|
func (w *gzipResponseWriter) Write(b []byte) (int, error) {
|
|
if w.Header().Get(echo.HeaderContentType) == "" {
|
|
w.Header().Set(echo.HeaderContentType, http.DetectContentType(b))
|
|
}
|
|
return w.Writer.Write(b)
|
|
}
|
|
|
|
func (w *gzipResponseWriter) Flush() {
|
|
w.Writer.(*gzip.Writer).Flush()
|
|
}
|
|
|
|
func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
|
return w.ResponseWriter.(http.Hijacker).Hijack()
|
|
}
|