aboutsummaryrefslogtreecommitdiff
path: root/fs.go
diff options
context:
space:
mode:
authorGravatar Co1a <aaron9shire@gmail.com> 2024-02-21 14:21:52 +0800
committerGravatar GitHub <noreply@github.com> 2024-02-21 07:21:52 +0100
commit5f81476d7cf339624b5fec57a06ee96d3e27d9c2 (patch)
tree62b06111db30c5895dc775f53bf5577f1092c06a /fs.go
parentLimit memory for fuzz testing (diff)
downloadfasthttp-5f81476d7cf339624b5fec57a06ee96d3e27d9c2.tar.gz
fasthttp-5f81476d7cf339624b5fec57a06ee96d3e27d9c2.tar.bz2
fasthttp-5f81476d7cf339624b5fec57a06ee96d3e27d9c2.zip
feat:support zstd compress and uncompressed (#1701)
* feat:support zstd compress and uncompressed * fix:real & stackless write using different pool to avoid get stackless.writer * fix:zstd normalize compress level * Change empty string checks to be more idiomatic (#1684) * chore:lint fix and rebase with master * chore:remove 1.18 test & upgrade compress version * fix:error default compress level * Fix lint --------- Co-authored-by: Erik Dubbelboer <erik@dubbelboer.com>
Diffstat (limited to 'fs.go')
-rw-r--r--fs.go74
1 files changed, 59 insertions, 15 deletions
diff --git a/fs.go b/fs.go
index 57260d1..4f2bbbf 100644
--- a/fs.go
+++ b/fs.go
@@ -18,6 +18,7 @@ import (
"github.com/andybalholm/brotli"
"github.com/klauspost/compress/gzip"
+ "github.com/klauspost/compress/zstd"
"github.com/valyala/bytebufferpool"
)
@@ -370,6 +371,7 @@ const FSCompressedFileSuffix = ".fasthttp.gz"
var FSCompressedFileSuffixes = map[string]string{
"gzip": ".fasthttp.gz",
"br": ".fasthttp.br",
+ "zstd": ".fasthttp.zst",
}
// FSHandlerCacheDuration is the default expiration duration for inactive
@@ -460,7 +462,9 @@ func (fs *FS) initRequestHandler() {
compressedFileSuffixes := fs.CompressedFileSuffixes
if compressedFileSuffixes["br"] == "" || compressedFileSuffixes["gzip"] == "" ||
- compressedFileSuffixes["br"] == compressedFileSuffixes["gzip"] {
+ compressedFileSuffixes["zstd"] == "" || compressedFileSuffixes["br"] == compressedFileSuffixes["gzip"] ||
+ compressedFileSuffixes["br"] == compressedFileSuffixes["zstd"] ||
+ compressedFileSuffixes["gzip"] == compressedFileSuffixes["zstd"] {
// Copy global map
compressedFileSuffixes = make(map[string]string, len(FSCompressedFileSuffixes))
for k, v := range FSCompressedFileSuffixes {
@@ -471,6 +475,7 @@ func (fs *FS) initRequestHandler() {
if fs.CompressedFileSuffix != "" {
compressedFileSuffixes["gzip"] = fs.CompressedFileSuffix
compressedFileSuffixes["br"] = FSCompressedFileSuffixes["br"]
+ compressedFileSuffixes["zstd"] = FSCompressedFileSuffixes["zstd"]
}
h := &fsHandler{
@@ -794,6 +799,7 @@ const (
defaultCacheKind CacheKind = iota
brotliCacheKind
gzipCacheKind
+ zstdCacheKind
)
func newCacheManager(fs *FS) cacheManager {
@@ -1032,14 +1038,19 @@ func (h *fsHandler) handleRequest(ctx *RequestCtx) {
fileEncoding := ""
byteRange := ctx.Request.Header.peek(strRange)
if len(byteRange) == 0 && h.compress {
- if h.compressBrotli && ctx.Request.Header.HasAcceptEncodingBytes(strBr) {
+ switch {
+ case h.compressBrotli && ctx.Request.Header.HasAcceptEncodingBytes(strBr):
mustCompress = true
fileCacheKind = brotliCacheKind
fileEncoding = "br"
- } else if ctx.Request.Header.HasAcceptEncodingBytes(strGzip) {
+ case ctx.Request.Header.HasAcceptEncodingBytes(strGzip):
mustCompress = true
fileCacheKind = gzipCacheKind
fileEncoding = "gzip"
+ case ctx.Request.Header.HasAcceptEncodingBytes(strZstd):
+ mustCompress = true
+ fileCacheKind = zstdCacheKind
+ fileEncoding = "zstd"
}
}
@@ -1097,10 +1108,13 @@ func (h *fsHandler) handleRequest(ctx *RequestCtx) {
hdr := &ctx.Response.Header
if ff.compressed {
- if fileEncoding == "br" {
+ switch fileEncoding {
+ case "br":
hdr.SetContentEncodingBytes(strBr)
- } else if fileEncoding == "gzip" {
+ case "gzip":
hdr.SetContentEncodingBytes(strGzip)
+ case "zstd":
+ hdr.SetContentEncodingBytes(strZstd)
}
}
@@ -1304,10 +1318,13 @@ nestedContinue:
if mustCompress {
var zbuf bytebufferpool.ByteBuffer
- if fileEncoding == "br" {
+ switch fileEncoding {
+ case "br":
zbuf.B = AppendBrotliBytesLevel(zbuf.B, w.B, CompressDefaultCompression)
- } else if fileEncoding == "gzip" {
+ case "gzip":
zbuf.B = AppendGzipBytesLevel(zbuf.B, w.B, CompressDefaultCompression)
+ case "zstd":
+ zbuf.B = AppendZstdBytesLevel(zbuf.B, w.B, CompressZstdDefault)
}
w = &zbuf
}
@@ -1406,20 +1423,28 @@ func (h *fsHandler) compressFileNolock(
}
return nil, errNoCreatePermission
}
- if fileEncoding == "br" {
+ switch fileEncoding {
+ case "br":
zw := acquireStacklessBrotliWriter(zf, CompressDefaultCompression)
_, err = copyZeroAlloc(zw, f)
if err1 := zw.Flush(); err == nil {
err = err1
}
releaseStacklessBrotliWriter(zw, CompressDefaultCompression)
- } else if fileEncoding == "gzip" {
+ case "gzip":
zw := acquireStacklessGzipWriter(zf, CompressDefaultCompression)
_, err = copyZeroAlloc(zw, f)
if err1 := zw.Flush(); err == nil {
err = err1
}
releaseStacklessGzipWriter(zw, CompressDefaultCompression)
+ case "zstd":
+ zw := acquireStacklessZstdWriter(zf, CompressZstdDefault)
+ _, err = copyZeroAlloc(zw, f)
+ if err1 := zw.Flush(); err == nil {
+ err = err1
+ }
+ releaseStacklessZstdWriter(zw, CompressZstdDefault)
}
_ = zf.Close()
_ = f.Close()
@@ -1443,20 +1468,28 @@ func (h *fsHandler) newCompressedFSFileCache(f fs.File, fileInfo fs.FileInfo, fi
err error
)
- if fileEncoding == "br" {
+ switch fileEncoding {
+ case "br":
zw := acquireStacklessBrotliWriter(w, CompressDefaultCompression)
_, err = copyZeroAlloc(zw, f)
if err1 := zw.Flush(); err == nil {
err = err1
}
releaseStacklessBrotliWriter(zw, CompressDefaultCompression)
- } else if fileEncoding == "gzip" {
+ case "gzip":
zw := acquireStacklessGzipWriter(w, CompressDefaultCompression)
_, err = copyZeroAlloc(zw, f)
if err1 := zw.Flush(); err == nil {
err = err1
}
releaseStacklessGzipWriter(zw, CompressDefaultCompression)
+ case "zstd":
+ zw := acquireStacklessZstdWriter(w, CompressZstdDefault)
+ _, err = copyZeroAlloc(zw, f)
+ if err1 := zw.Flush(); err == nil {
+ err = err1
+ }
+ releaseStacklessZstdWriter(zw, CompressZstdDefault)
}
defer func() { _ = f.Close() }()
@@ -1600,21 +1633,28 @@ func (h *fsHandler) newFSFile(f fs.File, fileInfo fs.FileInfo, compressed bool,
func readFileHeader(f io.Reader, compressed bool, fileEncoding string) ([]byte, error) {
r := f
var (
- br *brotli.Reader
- zr *gzip.Reader
+ br *brotli.Reader
+ zr *gzip.Reader
+ zsr *zstd.Decoder
)
if compressed {
var err error
- if fileEncoding == "br" {
+ switch fileEncoding {
+ case "br":
if br, err = acquireBrotliReader(f); err != nil {
return nil, err
}
r = br
- } else if fileEncoding == "gzip" {
+ case "gzip":
if zr, err = acquireGzipReader(f); err != nil {
return nil, err
}
r = zr
+ case "zstd":
+ if zsr, err = acquireZstdReader(f); err != nil {
+ return nil, err
+ }
+ r = zsr
}
}
@@ -1639,6 +1679,10 @@ func readFileHeader(f io.Reader, compressed bool, fileEncoding string) ([]byte,
releaseGzipReader(zr)
}
+ if zsr != nil {
+ releaseZstdReader(zsr)
+ }
+
return data, err
}