Files
mhr-cfw-go/internal/codec/codec.go
T
2026-05-04 07:17:57 +03:30

94 lines
1.6 KiB
Go

package codec
import (
"bytes"
"compress/gzip"
"compress/zlib"
"io"
"strings"
"github.com/andybalholm/brotli"
"github.com/klauspost/compress/zstd"
)
var (
hasBrotli = true
hasZstd = true
)
func SupportedEncodings() string {
codecs := []string{"gzip", "deflate"}
if hasBrotli {
codecs = append(codecs, "br")
}
if hasZstd {
codecs = append(codecs, "zstd")
}
return strings.Join(codecs, ", ")
}
func Decode(body []byte, encoding string) []byte {
if len(body) == 0 {
return body
}
enc := strings.TrimSpace(strings.ToLower(encoding))
if enc == "" || enc == "identity" {
return body
}
if strings.Contains(enc, ",") {
parts := strings.Split(enc, ",")
for i := len(parts) - 1; i >= 0; i-- {
body = Decode(body, strings.TrimSpace(parts[i]))
}
return body
}
switch enc {
case "gzip":
r, err := gzip.NewReader(bytes.NewReader(body))
if err != nil {
return body
}
defer r.Close()
out, err := io.ReadAll(r)
if err != nil {
return body
}
return out
case "deflate":
r, err := zlib.NewReader(bytes.NewReader(body))
if err == nil {
defer r.Close()
out, err := io.ReadAll(r)
if err == nil {
return out
}
}
return body
case "br":
if !hasBrotli {
return body
}
r := brotli.NewReader(bytes.NewReader(body))
out, err := io.ReadAll(r)
if err != nil {
return body
}
return out
case "zstd":
if !hasZstd {
return body
}
r, err := zstd.NewReader(bytes.NewReader(body))
if err != nil {
return body
}
defer r.Close()
out, err := io.ReadAll(r)
if err != nil {
return body
}
return out
}
return body
}