From 89f0affca7b661981475b37811b83d307438ba43 Mon Sep 17 00:00:00 2001 From: Max-Cheng Date: Sun, 11 Feb 2024 11:22:23 +0800 Subject: [PATCH] Change empty string checks to be more idiomatic (#1684) --- .golangci.yml | 3 +++ client.go | 2 +- expvarhandler/expvar.go | 2 +- fs.go | 47 +++++++++++++++++++++++++++++++++++++---- header_test.go | 2 +- http.go | 4 ++-- http_test.go | 4 ++-- server.go | 2 +- 8 files changed, 54 insertions(+), 12 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index d768d90f8b..6d91345124 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -68,6 +68,9 @@ linters-settings: "all", "-ST1000", # at least one file in a package should have a package comment ] + gocritic: + enabled-checks: + - emptyStringTest issues: # Show all issues from a linter. diff --git a/client.go b/client.go index 122894ba8a..b5493e9271 100644 --- a/client.go +++ b/client.go @@ -1825,7 +1825,7 @@ func newClientTLSConfig(c *tls.Config, addr string) *tls.Config { c = c.Clone() } - if len(c.ServerName) == 0 { + if c.ServerName == "" { serverName := tlsServerName(addr) if serverName == "*" { c.InsecureSkipVerify = true diff --git a/expvarhandler/expvar.go b/expvarhandler/expvar.go index 796954d194..b750261f96 100644 --- a/expvarhandler/expvar.go +++ b/expvarhandler/expvar.go @@ -53,7 +53,7 @@ func ExpvarHandler(ctx *fasthttp.RequestCtx) { func getExpvarRegexp(ctx *fasthttp.RequestCtx) (*regexp.Regexp, error) { r := string(ctx.QueryArgs().Peek("r")) - if len(r) == 0 { + if r == "" { return defaultRE, nil } rr, err := regexp.Compile(r) diff --git a/fs.go b/fs.go index 4a8e0f2950..0cfb08ec02 100644 --- a/fs.go +++ b/fs.go @@ -16,6 +16,7 @@ import ( "sync" "time" + "github.com/klauspost/compress/zstd" "github.com/andybalholm/brotli" "github.com/klauspost/compress/gzip" "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 @@ -459,8 +461,10 @@ func (fs *FS) initRequestHandler() { } compressedFileSuffixes := fs.CompressedFileSuffixes - if len(compressedFileSuffixes["br"]) == 0 || len(compressedFileSuffixes["gzip"]) == 0 || - compressedFileSuffixes["br"] == compressedFileSuffixes["gzip"] { + if compressedFileSuffixes["br"] == "" || compressedFileSuffixes["gzip"] == "" || + len(compressedFileSuffixes["zstd"]) == 0 || 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 len(fs.CompressedFileSuffix) > 0 { 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 { @@ -1040,6 +1046,11 @@ func (h *fsHandler) handleRequest(ctx *RequestCtx) { mustCompress = true fileCacheKind = gzipCacheKind fileEncoding = "gzip" + } else if ctx.Request.Header.HasAcceptEncodingBytes(strZstd) { + mustCompress = true + fileCacheKind = zstdCacheKind + fileEncoding = "zstd" + } } @@ -1101,6 +1112,8 @@ func (h *fsHandler) handleRequest(ctx *RequestCtx) { hdr.SetContentEncodingBytes(strBr) } else if fileEncoding == "gzip" { hdr.SetContentEncodingBytes(strGzip) + } else if fileEncoding == "zstd" { + hdr.SetContentEncodingBytes(strZstd) } } @@ -1308,6 +1321,8 @@ nestedContinue: zbuf.B = AppendBrotliBytesLevel(zbuf.B, w.B, CompressDefaultCompression) } else if fileEncoding == "gzip" { zbuf.B = AppendGzipBytesLevel(zbuf.B, w.B, CompressDefaultCompression) + } else if fileEncoding == "zstd" { + zbuf.B = AppendZstdBytesLevel(zbuf.B, w.B, CompressZstdDefault) } w = &zbuf } @@ -1420,6 +1435,13 @@ func (h *fsHandler) compressFileNolock( err = err1 } releaseStacklessGzipWriter(zw, CompressDefaultCompression) + } else if fileEncoding == "zstd" { + zw := acquireStacklessZstdWriter(zf, CompressZstdDefault) + _, err = copyZeroAlloc(zw, f) + if err1 := zw.Flush(); err == nil { + err = err1 + } + releaseStacklessZstdWriter(zw, CompressZstdDefault) } _ = zf.Close() _ = f.Close() @@ -1457,6 +1479,13 @@ func (h *fsHandler) newCompressedFSFileCache(f fs.File, fileInfo fs.FileInfo, fi err = err1 } releaseStacklessGzipWriter(zw, CompressDefaultCompression) + } else if fileEncoding == "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,8 +1629,9 @@ 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 @@ -1615,6 +1645,11 @@ func readFileHeader(f io.Reader, compressed bool, fileEncoding string) ([]byte, return nil, err } r = zr + } else if fileEncoding == "zstd" { + if zsr, err = acquireZstdReader(f); err != nil { + return nil, err + } + r = zsr } } @@ -1639,6 +1674,10 @@ func readFileHeader(f io.Reader, compressed bool, fileEncoding string) ([]byte, releaseGzipReader(zr) } + if zsr != nil { + releaseZstdReader(zsr) + } + return data, err } diff --git a/header_test.go b/header_test.go index eaa9a50a12..83b8a9c5a8 100644 --- a/header_test.go +++ b/header_test.go @@ -2355,7 +2355,7 @@ type bufioPeekReader struct { } func (r *bufioPeekReader) Read(b []byte) (int, error) { - if len(r.s) == 0 { + if r.s == "" { return 0, io.EOF } diff --git a/http.go b/http.go index 4785d12fe6..56723016f6 100644 --- a/http.go +++ b/http.go @@ -958,7 +958,7 @@ func (req *Request) MultipartForm() (*multipart.Form, error) { } req.multipartFormBoundary = string(req.Header.MultipartFormBoundary()) - if len(req.multipartFormBoundary) == 0 { + if req.multipartFormBoundary == "" { return nil, ErrNoMultipartForm } @@ -1014,7 +1014,7 @@ func marshalMultipartForm(f *multipart.Form, boundary string) ([]byte, error) { func WriteMultipartForm(w io.Writer, f *multipart.Form, boundary string) error { // Do not care about memory allocations here, since multipart // form processing is slow. - if len(boundary) == 0 { + if boundary == "" { return errors.New("form boundary cannot be empty") } diff --git a/http_test.go b/http_test.go index 7b526cbd85..098990a678 100644 --- a/http_test.go +++ b/http_test.go @@ -2214,7 +2214,7 @@ func testRequestSuccess(t *testing.T, method, requestURI, host, userAgent, body, if string(req1.Header.Method()) != expectedMethod { t.Fatalf("Unexpected method: %q. Expected %q", req1.Header.Method(), expectedMethod) } - if len(requestURI) == 0 { + if requestURI == "" { requestURI = "/" } if string(req1.Header.RequestURI()) != requestURI { @@ -2467,7 +2467,7 @@ func testRequestPostArgsError(t *testing.T, req *Request, s string) { t.Fatalf("Unexpected error when reading %q: %v", s, err) } ss := req.PostArgs().String() - if len(ss) != 0 { + if ss != "" { t.Fatalf("unexpected post args: %q. Expecting empty post args", ss) } } diff --git a/server.go b/server.go index 95eb2c0c81..dbee2a4f0d 100644 --- a/server.go +++ b/server.go @@ -1736,7 +1736,7 @@ func (s *Server) ServeTLSEmbed(ln net.Listener, certData, keyData []byte) error // This function allows programmer to handle multiple domains // in one server structure. See examples/multidomain. func (s *Server) AppendCert(certFile, keyFile string) error { - if len(certFile) == 0 && len(keyFile) == 0 { + if certFile == "" && keyFile == "" { return errNoCertOrKeyProvided }