* Response.ContentEncoding(): store as field
The CE is not so often used for plain APIs responses and even not so often used for static files and on the fly compression.
But still it should be checked each time.
Also having a dedicated field getter and setter simplifies code
* header.go Use shorter Response.setNonSpecial() and Request.setNonSpecial() methods instead of SetCanonical()
The change should improve performance because the setSpecialHeader() call is omitted.
As a downside on adding a new basic header field all putHeader() must be replaced with a direct getter and setter.
New Functions:
CompressHandlerBrotliLevel(h RequestHandler, brotliLevel, otherLevel int) RequestHandler
Request.BodyUnbrotli() ([]byte, error)
Response.BodyUnbrotli() ([]byte, error)
AppendBrotliBytesLevel(dst, src []byte, level int) []byte
WriteBrotliLevel(w io.Writer, p []byte, level int) (int, error)
WriteBrotli(w io.Writer, p []byte) (int, error)
AppendBrotliBytes(dst, src []byte) []byte
WriteUnbrotli(w io.Writer, p []byte) (int, error)
AppendUnbrotliBytes(dst, src []byte) ([]byte, error)
New Constants:
CompressBrotliNoCompression
CompressBrotliBestSpeed
CompressBrotliBestCompression
CompressBrotliDefaultCompression
Brotli compression levels are different from gzip/flate. Because of this we have separate level constants and CompressHandlerBrotliLevel takes 2 levels.
I didn't add Brotli support to CompressHandler as this could cause a spike in CPU usage when users upgrade fasthttp.
fasthttp.CompressBrotliDefaultCompression is not the same as
brotli.DefaultCompression. brotli.DefaultCompression is more than twice
as slow as fasthttp.CompressBrotliDefaultCompression which I thought was
unreasonable as default.